:root{
  --ink:#0B0E14; --ink-2:#111623; --ink-3:#161D2E; --line:#1F2839; --line-hi:#33405A;
  --paper:#E8E6E1; --paper-2:#A8B0C0; --paper-3:#6C7488;
  --lamp:#F2A93B; --lamp-dim:#7A5620;
  --signal:#74D0C4; --crit:#E2635A;
  --display:"Bricolage Grotesque","Work Sans",system-ui,sans-serif;
  --body:"Work Sans",system-ui,-apple-system,sans-serif;
  --mono:"IBM Plex Mono",ui-monospace,monospace;
}
*{box-sizing:border-box}
body{
  margin:0;background:var(--ink);color:var(--paper);
  font-family:var(--body);font-weight:300;font-size:16px;line-height:1.6;
  -webkit-font-smoothing:antialiased;overflow-x:hidden;
  user-select:none;
}

#entry{
  position:relative;min-height:100svh;width:100vw;height:100vh;
  display:flex;align-items:center;justify-content:center;
  overflow:hidden;background:var(--ink);
}

.house{
  position:fixed;inset:0;width:100vw;height:100vh;
  display:flex;align-items:center;justify-content:center;
  z-index:0;overflow:hidden;
}
.house .frame{
  position:absolute;
  inset:0;width:100%;height:100%;
  overflow:hidden;pointer-events:auto;
}
.house .h-base,
.house img{
  position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;object-position:center;display:block;z-index:1;
  user-select:none;-webkit-user-select:none;
  -webkit-user-drag:none;user-drag:none;
  pointer-events:none;
}

/* Organic Sconce Glow Breathing */
.sconce-glow{
  position:absolute;inset:0;pointer-events:none;z-index:2;
  background:radial-gradient(circle at 18% 70%, rgba(242,169,59,.1) 0%, transparent 22%),
             radial-gradient(circle at 45% 66%, rgba(242,169,59,.12) 0%, transparent 25%),
             radial-gradient(circle at 76% 74%, rgba(242,169,59,.1) 0%, transparent 22%);
  animation:sconce-breath 5s ease-in-out infinite alternate;
}

@keyframes sconce-breath{
  0%{opacity:.6;filter:brightness(.95)}
  40%{opacity:.88;filter:brightness(1.08)}
  70%{opacity:.72;filter:brightness(1.0)}
  100%{opacity:1;filter:brightness(1.15)}
}

/* Atmospheric Particle Canvas */
.atmo-canvas{
  position:absolute;inset:0;width:100%;height:100%;
  pointer-events:none;z-index:3;
}

/* Individual room illuminated layers */
.room-lit-img{
  position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;object-position:center;display:block;opacity:0;
  transition:opacity .45s cubic-bezier(.16,1,.3,1);
  pointer-events:none;z-index:2;
}
.room-lit-img.active{
  opacity:1;
}

/* 16:9 Widescreen Architectural Window Clip-Paths */
.room-lit-img[data-room="chess"]{
  clip-path:inset(31.0% 45.5% 50.0% 40.5% round 4px);
}
.room-lit-img[data-room="chessbook"]{
  clip-path:inset(31.0% 31.5% 50.0% 54.0% round 4px);
}
.room-lit-img[data-room="monitor"]{
  clip-path:inset(40.2% 62.7% 47.7% 17.9% round 4px);
}
.room-lit-img[data-room="library"]{
  clip-path:inset(52.0% 13.0% 28.0% 63.0% round 4px);
}

/* Interactive Room Hotspots (Invisible, no borders) */
.rooms-layer{
  position:absolute;inset:0;z-index:10;pointer-events:none;
}
.rooms-layer .loading{
  position:absolute;left:50%;bottom:24px;transform:translateX(-50%);
  font-family:var(--mono);font-size:10px;letter-spacing:.2em;text-transform:uppercase;
  color:var(--paper-3);margin:0;opacity:.6;
}

.room-hotspot{
  position:absolute;pointer-events:auto;cursor:pointer;
  display:flex;align-items:center;justify-content:center;
  user-select:none;
}

/* Minimal, nonchalant typography reveal - no shapes, no pills, no borders */
.room-label{
  position:absolute;
  opacity:0;
  transform:translateY(4px);
  color:#fff;
  font-family:var(--display);
  font-weight:500;
  font-size:18px;
  letter-spacing:.03em;
  text-shadow:0 2px 12px rgba(0,0,0,.9), 0 0 20px rgba(0,0,0,.7);
  transition:opacity .3s ease-out, transform .3s ease-out;
  pointer-events:none;
  white-space:nowrap;
  z-index:12;
}

.room-hotspot:hover .room-label{
  opacity:1;
  transform:translateY(0);
}

@media (max-width:640px){
  .room-label{font-size:14px}
}
@media (prefers-reduced-motion:reduce){
  *{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}
}

/* --- the machiya -----------------------------------------------------------
   Riku is served a different building (functions/index.js), and it has its own
   windows. Without a clip-path an overlay covers the whole frame, so hovering
   her one room lit up the entire house as if it were a single room — which is
   what it looked like: one glowing house and a stack of identical locked spots
   piled on the same square.

   Each pane is now its own region. Only the room she actually holds gets an
   overlay; the rest stay dark, because a locked window has nothing to show.
   Measured off the plate: 1672x941, F is the tatami room on the right. */
body.house-riku .room-lit-img[data-room="riku"] {
  clip-path: inset(51.6% 7.6% 24.3% 70.5% round 3px);
}

/* Her other two panes. Same plate, same measurements as the room hotspots in
   app.js — if one moves, the other has to move with it or the light lands on a
   window she is not hovering. */
body.house-riku .room-lit-img[data-room="games"] {
  clip-path: inset(23.6% 16.3% 63.2% 63.1% round 3px);
}
body.house-riku .room-lit-img[data-room="summaries"] {
  clip-path: inset(24.7% 60.5% 64.7% 22.6% round 3px);
}

/* The villa's two newest windows. `riku` never had one either, so holding that
   room lit the whole building the same way the machiya used to — same bug,
   same fix. Numbers mirror ROOM_HOTSPOTS in app.js; move one, move both. */
.room-lit-img[data-room="riku"] {
  clip-path: inset(52.0% 48.0% 28.0% 38.0% round 4px);
}
.room-lit-img[data-room="games"] {
  clip-path: inset(40.0% 23.5% 49.0% 69.0% round 4px);
}
.room-lit-img[data-room="summaries"] {
  clip-path: inset(50.0% 3.0% 29.0% 89.5% round 4px);
}

/* The ground-floor shoji, which is where her copy of the books lives. */
body.house-riku .room-lit-img[data-room="chessbook"] {
  clip-path: inset(56.1% 68.2% 29.0% 8.3% round 3px);
}

/* Her notebook: the small pane over the porch on the machiya, and a window
   between the chess room and the library on the villa. */
body.house-riku .room-lit-img[data-room="notes"] {
  clip-path: inset(26.8% 43.1% 64.7% 43.5% round 3px);
}
.room-lit-img[data-room="notes"] {
  clip-path: inset(40.0% 48.0% 50.0% 44.0% round 4px);
}

/* Jessie's two. The left wing of the villa is two lit rooms stacked on one
   floor line, and the monitor's pane used to cover both of them; it now stops
   at the floor and the dining room below — the one with the picture already
   hung on its wall — is the tier list. The song room is the pair of warm
   alcoves at the far left of the elevation.

   inset() is (top, right, bottom, left), so these are ROOM_HOTSPOTS in app.js
   read inside-out: right = 100 - left - width. Move one, move both. */
.room-lit-img[data-room="tierlist"]{
  clip-path:inset(55.0% 67.4% 31.5% 22.0% round 4px);
}
.room-lit-img[data-room="songs"]{
  clip-path:inset(55.3% 83.2% 34.1% 6.3% round 4px);
}

/* --- the bush house --------------------------------------------------------
   Jessie's building. Same 1672x941 plate as the villa and the machiya, so the
   dark base and the lit overlay register pixel for pixel.

   /* These are JESSIE_PANES in app.js read inside-out: inset() is
      (top, right, bottom, left), so right = 100 - left - width. They were derived
      by subtracting the dark plate from the lit one and taking the boxes that
      changed, which is why they are not round numbers — they are where the
      photograph's windows actually are. Move one, move both. */
body.house-jessie .room-lit-img[data-room="monitor"] {   /* the living slider */
  clip-path: inset(44.5% 54.6% 38.1% 37.2% round 3px);
}
body.house-jessie .room-lit-img[data-room="tierlist"] {  /* the kitchen slider */
  clip-path: inset(44.5% 62.8% 40.0% 29.2% round 3px);
}
body.house-jessie .room-lit-img[data-room="songs"] {     /* the pane between them */
  clip-path: inset(44.6% 45.1% 45.6% 49.3% round 3px);
}

/* Room 12's pane on each building. inset() is (top, right, bottom, left), so
   right = 100 - left - width — these mirror ROOM_HOTSPOTS and JESSIE_ROOM_PANE
   in app.js. Move one, move both. */
.room-lit-img[data-room="words"]{
  clip-path:inset(53.5% 44.7% 35.5% 51.8% round 4px);
}
body.house-jessie .room-lit-img[data-room="words"]{
  clip-path:inset(44.7% 24.3% 45.4% 71.8% round 3px);
}

/* --- the entrance on a touchscreen -----------------------------------------
   Hover does two jobs here that nothing on a phone can do: it tells you a pane
   is a door at all, and it names it. Without them the house is a dark
   photograph with invisible tap targets, which is exactly what it was.

   So each door she can actually open carries a small breathing marker — enough
   to say "here", not enough to spoil the picture — and the first tap does what
   hover did. Sealed panes get no marker on purpose: a locked room should not
   advertise itself to someone who cannot open it. */
body.house-touch .room-hotspot.open::after{
  content:"";
  position:absolute;left:50%;top:50%;
  width:10px;height:10px;margin:-5px 0 0 -5px;
  border-radius:50%;
  background:rgba(242,169,59,.9);
  box-shadow:0 0 0 4px rgba(242,169,59,.18),0 0 14px 3px rgba(242,169,59,.5);
  animation:hbf-door-pulse 2.6s ease-in-out infinite;
  pointer-events:none;
  transition:opacity .3s ease-out;
}
@keyframes hbf-door-pulse{
  0%,100%{transform:scale(1);opacity:.85}
  50%{transform:scale(1.45);opacity:.45}
}
/* Armed: the marker steps aside and the name arrives, same as hover. */
body.house-touch .room-hotspot.is-armed::after{opacity:0}
body.house-touch .room-hotspot.is-armed .room-label{
  opacity:1;transform:translateY(0);
}
/* A second tap opens it, so say so once the pane is lit. */
body.house-touch .room-hotspot.is-armed .room-label::after{
  content:" \00B7 tap again";
  font-family:var(--mono,"IBM Plex Mono",monospace);
  font-size:11px;letter-spacing:.06em;opacity:.7;font-weight:400;
}
@media (prefers-reduced-motion:reduce){
  body.house-touch .room-hotspot.open::after{animation:none}
}

/* The fallback marker, for a pointer that has hunted and not found a door.
   Deliberately quieter than the touch one: on a pointer device it is a nudge
   after the introduction failed, not the primary affordance. Fades the moment
   she hovers anything. */
.rooms-layer.show-hints .room-hotspot.open::after{
  content:"";
  position:absolute;left:50%;top:50%;
  width:8px;height:8px;margin:-4px 0 0 -4px;
  border-radius:50%;
  background:rgba(242,169,59,.75);
  box-shadow:0 0 12px 3px rgba(242,169,59,.4);
  animation:hbf-door-pulse 2.6s ease-in-out infinite;
  pointer-events:none;
}
.rooms-layer.show-hints .room-hotspot.open:hover::after{opacity:0}

/* --- a phone held upright --------------------------------------------------
   Every plate is a 1672x941 photograph, and the frame was the whole viewport
   with object-fit: cover. On a 16:9 screen that IS the photograph. On a phone
   held upright it is a 28%-wide slice of its middle, blown up -- and the
   doors, which are percentages of the frame rather than of the picture, stayed
   where the windows would be on the full photograph: on the roof, in the sky,
   on bare wall. The lit panes are clip-paths of the same frame, so they lit
   wall too.

   Upright, the frame therefore takes the photograph's own shape. Every
   percentage in app.js lands on its window again, the whole building shows
   across the width, and the night carries on above it (app.js stretches the
   stars over it). The doors are also listed underneath (.room-list), because
   a window here is the size of a thumbnail. A landscape screen matches none of
   this, so the desktop is exactly as it was. */
.room-list{display:none}

@media (max-aspect-ratio:1/1){
  :root{--night:#05070B}
  body{background:var(--night)}
  #entry{
    width:100%;height:auto;min-height:100svh;
    flex-direction:column;align-items:stretch;justify-content:flex-start;
    background:var(--night);
  }
  .house{
    position:relative;inset:auto;width:100%;height:auto;flex:1 0 auto;
    flex-direction:column;align-items:stretch;justify-content:flex-end;
    padding-top:max(64px,9svh);
  }
  .house .frame{
    position:relative;inset:auto;width:100%;height:auto;flex:none;
    aspect-ratio:1672/941;overflow:visible;
  }
  /* The plate's own sky and drive fade into the night instead of stopping
     on a hard edge. The photographs' skies are hazier than a flat colour,
     so the fade has to be long or it reads as a seam. */
  .house .h-base,.house .room-lit-img{
    -webkit-mask-image:linear-gradient(to bottom,transparent 0,#000 18%,#000 88%,transparent 100%);
            mask-image:linear-gradient(to bottom,transparent 0,#000 18%,#000 88%,transparent 100%);
  }
  /* Thirteen breathing markers on a house one screen wide were a polka-dot
     pattern over the picture. Upright, the windows she holds glow instead,
     softly and all the time, and come up to full when pressed: here or in
     the list below. The hotspots are still there to tap. */
  body.house-touch .room-hotspot.open::after{display:none}
  .room-lit-img.held{opacity:.42}
  .room-lit-img.held.active{opacity:1}
  .room-hotspot.lab-l .room-label{left:0}
  .room-hotspot.lab-r .room-label{right:0}

  .room-list{
    display:block;position:relative;z-index:1;
    padding:6px 16px calc(22px + env(safe-area-inset-bottom));
  }
  .room-list-head{
    margin:0 2px 12px;
    font-family:var(--mono);font-size:10px;font-weight:500;line-height:1;
    letter-spacing:.22em;text-transform:uppercase;color:var(--paper-3);
  }
  .room-list-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}
  /* An odd one out spans the row instead of leaving a hole beside it. */
  .room-key:last-child:nth-child(odd){grid-column:1/-1}
  .room-key{
    display:flex;align-items:center;gap:11px;min-height:58px;
    padding:10px 12px 10px 14px;border-radius:12px;
    background:rgba(17,22,35,.72);border:1px solid var(--line);
    color:var(--paper);text-decoration:none;
    -webkit-tap-highlight-color:transparent;
    transition:background .16s ease,border-color .16s ease,transform 90ms ease;
  }
  .room-key-dot{
    flex:none;width:7px;height:7px;border-radius:50%;
    background:var(--lamp);box-shadow:0 0 10px 2px rgba(242,169,59,.4);
  }
  .room-key-text{display:flex;flex-direction:column;gap:3px;min-width:0}
  .room-key-name{
    font-family:var(--display);font-size:15px;font-weight:600;line-height:1.15;
    letter-spacing:-.005em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  }
  .room-key-sub{font-size:11.5px;font-weight:400;line-height:1.2;letter-spacing:.06em;color:var(--paper-3)}
  /* Pressed, a key warms the way its window does. */
  .room-key.is-lit{background:rgba(242,169,59,.09);border-color:rgba(242,169,59,.5)}
  .room-key.is-lit .room-key-dot{box-shadow:0 0 0 4px rgba(242,169,59,.18),0 0 16px 4px rgba(242,169,59,.55)}
  .room-key:active{transform:scale(.985)}
  .room-key:focus-visible{outline:2px solid var(--lamp);outline-offset:2px}
}
@media (max-aspect-ratio:1/1) and (min-width:600px){
  .room-list{padding-left:24px;padding-right:24px}
  .room-list-grid{grid-template-columns:repeat(3,minmax(0,1fr))}
  .room-key:last-child:nth-child(odd){grid-column:auto}
}

/* --- a phone on its side ---------------------------------------------------
   Wide and short (844x390): cover cut off the top and bottom, and the doors
   slid off their windows for the same reason as above. Here the plate is
   fitted whole and centred, the night fills the sides, and the doors stay on
   the house; at this size the windows are big enough to tap. */
@media (orientation:landscape) and (max-height:500px){
  :root{--night:#05070B}
  body,#entry,.house{background:var(--night)}
  .house{height:100svh}
  .house .frame{
    position:relative;inset:auto;flex:none;overflow:visible;
    width:min(100vw,calc(100svh * 1672 / 941));
    height:min(calc(100vw * 941 / 1672),100svh);
  }
  .house .h-base,.house .room-lit-img{
    -webkit-mask-image:linear-gradient(to right,transparent 0,#000 4%,#000 96%,transparent 100%);
            mask-image:linear-gradient(to right,transparent 0,#000 4%,#000 96%,transparent 100%);
  }
  .room-hotspot.lab-l .room-label{left:0}
  .room-hotspot.lab-r .room-label{right:0}
}
