/* ==========================================================================
   Nook — interface
   The room is the interface: transparent buttons sit exactly over the
   objects in the SVG, and small tags carry labels and sliders.
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }

html, body { height: 100%; margin: 0; }

body {
  background: var(--wall);
  color: var(--text);
  font-family: var(--font-serif);
  font-optical-sizing: auto;
  font-size: var(--step-0);
  line-height: 1.5;
  overflow: hidden;
  -webkit-font-smoothing: antialiased;
}

button, input { font: inherit; color: inherit; }

[hidden] { display: none !important; }

.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
}

/* --- Stage and scene ------------------------------------------------------
   The scene keeps the aspect of its viewBox, so a button placed in viewBox
   units lands exactly on its object. On wide screens it covers the window;
   below the breakpoint it switches to a portrait crop (see room.js, which
   copies --vb-* into the SVG viewBox). */
:root { --handle-h: 0px; }

.stage {
  position: fixed;
  inset: 0;
  overflow: hidden;
  container-type: size;
}

.scene {
  --vb-x: 0;
  --vb-y: 0;
  --vb-w: 1600;
  --vb-h: 1000;

  position: absolute;
  left: 50%;
  top: 50%;
  width: max(100cqw, 100cqh * var(--vb-w) / var(--vb-h));
  aspect-ratio: var(--vb-w) / var(--vb-h);
  translate: -50% -50%;
  animation: room-in var(--dur-slow) var(--ease-out) both;
}

.scene > .room { position: absolute; inset: 0; }

@keyframes room-in { from { opacity: 0; } }

/* Grain over the whole page, so the wall around a cropped scene matches. */
.grain-layer {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 20;
}

/* --- Objects -------------------------------------------------------------- */
.obj {
  position: absolute;
  left:   calc((var(--x) - var(--vb-x)) / var(--vb-w) * 100%);
  top:    calc((var(--y) - var(--vb-y)) / var(--vb-h) * 100%);
  width:  calc(var(--w) / var(--vb-w) * 100%);
  height: calc(var(--h) / var(--vb-h) * 100%);
}

/* Bounds in viewBox units (x, y, w, h). Later entries sit on top. */
.obj[data-obj="window"] { --x: 150;  --y: 120; --w: 450; --h: 440; }
.obj[data-obj="note"]   { --x: 640;  --y: 302; --w: 148; --h: 132; }
.obj[data-obj="stove"]  { --x: 1284; --y: 540; --w: 232; --h: 346; }
.obj[data-obj="radio"]  { --x: 1030; --y: 500; --w: 200; --h: 144; }
.obj[data-obj="lamp"]   { --x: 800;  --y: 396; --w: 146; --h: 246; }
.obj[data-obj="clock"]  { --x: 612;  --y: 552; --w: 184; --h: 92; }
.obj[data-obj="mug"]    { --x: 490;  --y: 500; --w: 96;  --h: 144; }
.obj[data-obj="cat"]    { --x: 256;  --y: 548; --w: 210; --h: 96; }

/* The cat and the mug sit in front of the window's lower edge. */
.obj { z-index: 1; }
.obj[data-obj="window"] { z-index: 0; }
.obj:hover, .obj:has(:focus-visible), .obj[data-active] { z-index: 5; }

.obj-btn {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  padding: 0;
  border: 0;
  border-radius: 6px;
  background: transparent;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

/* Focus: on-palette, visible on every wall colour (≥ 4:1, see DESIGN.md). */
:focus { outline: none; }
:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 4px;
}
.obj-btn:focus-visible { outline-offset: 6px; }

/* --- Tags: label (+ slider) beside an object ------------------------------ */
.tag {
  position: absolute;
  left: 50%;
  bottom: 100%;
  padding-bottom: 10px;          /* hover bridge between object and tag */
  translate: -50% 4px;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition:
    opacity var(--dur-quick) var(--ease-out),
    translate var(--dur-quick) var(--ease-out),
    visibility 0s linear var(--dur-quick);
}

/* Open on hover, on keyboard focus (not on a mouse click), or after a tap. */
@media (hover: hover) {
  .obj:hover .tag { opacity: 1; visibility: visible; pointer-events: auto; translate: -50% 0; transition-delay: 0s; }
}
.obj:has(:focus-visible) .tag,
.obj[data-active] .tag {
  opacity: 1; visibility: visible; pointer-events: auto; translate: -50% 0; transition-delay: 0s;
}

.tag-inner {
  display: grid;
  gap: 2px;
  min-width: 168px;
  padding: 8px 12px 6px;
  border: 1px solid color-mix(in oklab, var(--paper), transparent 84%);
  border-radius: 2px;
  background: var(--ink);
  white-space: nowrap;
}

.tag-label {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  font-size: var(--step--1);
  line-height: 1.3;
}
.tag-state { color: var(--text-muted); font-style: italic; }

.tag-input {
  width: 220px;
  margin: 6px 0 4px;
  padding: 6px 8px;
  border: 0;
  border-bottom: 1px solid color-mix(in oklab, var(--paper), transparent 60%);
  border-radius: 0;
  background: transparent;
  color: var(--text);
  font-style: italic;
  font-size: 16px;           /* 16px keeps iOS from zooming on focus */
}
.tag-input::placeholder { color: var(--text-muted); opacity: 1; }
.tag-input:focus-visible { outline: none; border-bottom-color: var(--focus); }

.tag-actions { display: flex; gap: 16px; margin-top: 2px; }

/* Quiet text buttons: underlined words, no boxes. */
.text-btn {
  min-height: 32px;
  padding: 4px 0;
  border: 0;
  background: none;
  color: var(--text);
  font-size: var(--step--1);
  text-decoration: underline;
  text-decoration-color: color-mix(in oklab, var(--paper), transparent 60%);
  text-underline-offset: 3px;
  cursor: pointer;
  transition: text-decoration-color var(--dur-quick) var(--ease-out);
}
.text-btn:hover { text-decoration-color: var(--lamp); }
@media (pointer: coarse) { .text-btn { min-height: 44px; padding: 0 4px; } }

/* --- Status line (and, on phones, the big readout) ------------------------ */
:root { --hud-h: 0px; }

.hud {
  position: fixed;
  z-index: 15;
  top: 0;
  left: 0;
  right: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: max(22px, env(safe-area-inset-top)) 16px 0;
  text-align: center;
  pointer-events: none;
}

.status {
  max-width: 40ch;
  margin: 0;
  font-size: var(--step-2);
  font-variation-settings: "opsz" 36;
  line-height: 1.3;
  color: var(--text);
  text-wrap: balance;
}

.readout { display: none; }

/* --- Settings popover ------------------------------------------------------ */
.popover {
  position: fixed;
  z-index: 30;
  width: 312px;
  padding: 16px 18px 10px;
  border: 1px solid color-mix(in oklab, var(--paper), transparent 84%);
  border-radius: 2px;
  background: var(--ink);
  color: var(--text);
  opacity: 0;
  translate: 0 6px;
  transition: opacity var(--dur-calm) var(--ease-out), translate var(--dur-calm) var(--ease-out);
}
.popover[hidden] { display: none; }
.popover[data-open] { opacity: 1; translate: 0 0; }

.popover-title {
  margin: 0 0 6px;
  font-size: var(--step-1);
  font-weight: 400;
}

.field {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-height: 44px;
  border-bottom: 1px solid color-mix(in oklab, var(--paper), transparent 90%);
}
.field-input { display: flex; align-items: baseline; gap: 6px; }
.field input {
  width: 3.2em;
  padding: 4px 2px;
  border: 0;
  border-bottom: 1px solid color-mix(in oklab, var(--paper), transparent 60%);
  border-radius: 0;
  background: transparent;
  color: var(--text);
  font-size: 16px;
  font-variant-numeric: tabular-nums lining-nums;
  text-align: right;
  -moz-appearance: textfield;
  appearance: textfield;
}
.field input::-webkit-inner-spin-button,
.field input::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
.field input:focus-visible { outline: none; border-bottom-color: var(--focus); }
.unit { width: 4.4em; color: var(--text-muted); font-size: var(--step--1); }

.check {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  min-height: 44px;
  padding: 12px 0 2px;
  cursor: pointer;
}
.check input {
  appearance: none;
  -webkit-appearance: none;
  flex: none;
  display: grid;
  place-content: center;
  width: 18px;
  height: 18px;
  margin: 2px 0 0;
  border: 1.5px solid var(--text-muted);
  border-radius: 3px;
  cursor: pointer;
  transition: background-color var(--dur-quick) var(--ease-out), border-color var(--dur-quick) var(--ease-out);
}
.check input::before {
  content: "";
  width: 9px;
  height: 5px;
  border-left: 2px solid var(--ink);
  border-bottom: 2px solid var(--ink);
  rotate: -45deg;
  translate: 0 -1px;
  opacity: 0;
}
.check input:checked { background: var(--lamp); border-color: var(--lamp); }
.check input:checked::before { opacity: 1; }
.check input:focus-visible { outline-offset: 3px; }

.popover-actions { display: flex; justify-content: flex-end; }

.settings-note {
  margin: 0;
  color: var(--text-muted);
  font-size: var(--step--1);
  font-style: italic;
}
.settings-note:empty { display: none; }

/* Shortcuts: centred, a short list of keys. */
.popover--centre {
  left: 50%;
  top: 50%;
  translate: -50% calc(-50% + 6px);
  width: min(360px, calc(100vw - 32px));
}
.popover--centre[data-open] { translate: -50% -50%; }

.keys { display: grid; gap: 2px; margin: 4px 0 8px; }
.keys > div {
  display: grid;
  grid-template-columns: 120px 1fr;
  align-items: baseline;
  gap: 12px;
  min-height: 34px;
  border-bottom: 1px solid color-mix(in oklab, var(--paper), transparent 90%);
}
.keys dt, .keys dd { margin: 0; }
.keys dd { font-size: var(--step-0); }

kbd {
  display: inline-block;
  min-width: 1.9em;
  padding: 1px 6px 2px;
  border: 1px solid color-mix(in oklab, var(--paper), transparent 70%);
  border-bottom-width: 2px;
  border-radius: 3px;
  font-family: inherit;
  font-size: var(--step--1);
  text-align: center;
}

/* A quiet way in to the shortcuts, for people with a keyboard. */
.keys-btn {
  position: fixed;
  z-index: 15;
  right: 20px;
  bottom: 14px;
  color: var(--text-muted);
}
@media (hover: none), (pointer: coarse) {
  .keys-btn { display: none; }
}

/* --- Sliders -------------------------------------------------------------- */
.slider {
  --pct: 50%;
  -webkit-appearance: none;
  appearance: none;
  display: block;
  width: 100%;
  height: 28px;
  margin: 0;
  background: transparent;
  cursor: pointer;
  touch-action: pan-y;
}
.slider::-webkit-slider-runnable-track {
  height: 2px;
  border-radius: 1px;
  background: linear-gradient(to right, var(--lamp) var(--pct), color-mix(in oklab, var(--paper), transparent 62%) var(--pct));
}
.slider::-moz-range-track {
  height: 2px;
  border-radius: 1px;
  background: color-mix(in oklab, var(--paper), transparent 62%);
}
.slider::-moz-range-progress { height: 2px; background: var(--lamp); }
.slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 16px;
  height: 16px;
  margin-top: -7px;
  border: 0;
  border-radius: 50%;
  background: var(--lamp);
  transition: scale var(--dur-quick) var(--ease-out);
}
.slider::-moz-range-thumb {
  width: 16px;
  height: 16px;
  border: 0;
  border-radius: 50%;
  background: var(--lamp);
}
.slider:active::-webkit-slider-thumb { scale: 1.15; }
.slider:focus-visible { outline-offset: 2px; border-radius: 2px; }

/* --- Shelf drawer (narrow layout only) ------------------------------------ */
.drawer { display: none; }

/* ==========================================================================
   Narrow / portrait layout
   Square-ish crop around the window and desk, anchored above the drawer.
   The radio and stove leave the frame; all sound controls live on the shelf.
   Keep this query in sync with NARROW_QUERY in js/room.js.
   ========================================================================== */
@media (max-width: 720px), (max-aspect-ratio: 13/10) {
  :root { --handle-h: calc(60px + env(safe-area-inset-bottom)); }

  .scene {
    --vb-x: 172;
    --vb-y: 40;
    --vb-w: 624;
    --vb-h: 960;

    /* Full width when possible. The floor may slip behind the shelf (up to a
       quarter of the crop) before the scene shrinks. Sits on the shelf when
       the screen is tall, tucks under the readout when it is short. */
    --scene-w: min(100cqw, (100cqh - var(--handle-h) - var(--hud-h)) * 4 / 3 * var(--vb-w) / var(--vb-h));
    width: var(--scene-w);
    top: max(var(--hud-h), 100cqh - var(--handle-h) - var(--scene-w) * var(--vb-h) / var(--vb-w));
    translate: -50% 0;
  }

  .obj[data-obj="stove"],
  .obj[data-obj="radio"],
  .obj[data-obj="lamp"] { display: none; }

  .keys-btn { display: none; }

  /* Room for the readout and status line above the scene. */
  :root { --hud-h: calc(118px + env(safe-area-inset-top)); }

  .hud { padding-top: max(18px, env(safe-area-inset-top)); gap: 0; }

  .readout {
    display: block;
    min-height: 44px;
    padding: 0 14px;
    border: 0;
    background: transparent;
    color: var(--lamp);
    font-family: var(--font-mono);
    font-size: var(--step-3);
    font-weight: 400;
    letter-spacing: 0.02em;
    line-height: 1.25;
    cursor: pointer;
    pointer-events: auto;
    -webkit-tap-highlight-color: transparent;
    transition: color var(--dur-calm) var(--ease-out);
  }
  .readout[data-phase="short"],
  .readout[data-phase="long"] { color: var(--break-ink); }
  .readout[data-status="paused"] { color: var(--text-muted); }

  .status { font-size: var(--step-0); font-variation-settings: normal; }

  .popover {
    left: 16px;
    right: 16px;
    top: auto;
    bottom: calc(var(--handle-h) + 12px);
    width: auto;
  }

  /* Objects near the right edge open their tags leftwards. */
  .obj[data-obj="note"] .tag,
  .obj[data-obj="clock"] .tag { left: auto; right: 4px; translate: 0 4px; }
  .obj[data-obj="note"]:is(:hover, :has(:focus-visible), [data-active]) .tag,
  .obj[data-obj="clock"]:is(:hover, :has(:focus-visible), [data-active]) .tag { translate: 0 0; }

  /* Sliders live on the shelf here; tags keep just the label. */
  .obj .slider { display: none; }
  .tag-inner { min-width: 0; }

  .drawer {
    display: block;
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 10;
    translate: 0 calc(100% - var(--handle-h));
    transition: translate var(--dur-calm) var(--ease-out);
    background: var(--wood-dark);
    color: var(--text);
    padding-bottom: env(safe-area-inset-bottom);
  }
  .drawer[data-open="true"] { translate: 0 0; }

  /* The lip of the shelf: a lit wooden edge with a shadow under it. */
  .drawer::before {
    content: "";
    display: block;
    height: 8px;
    background: var(--wood-lit);
    box-shadow: 0 3px 0 var(--ink);
  }

  .drawer-handle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    min-height: 52px;
    padding: 6px 20px 0;
    border: 0;
    background: transparent;
    font-size: var(--step-0);
    text-align: left;
    cursor: pointer;
  }
  .drawer-summary { color: var(--text-muted); font-style: italic; font-size: var(--step--1); }

  /* A small drawn chevron: two strokes, no icon font. */
  .drawer-chevron {
    width: 10px;
    height: 10px;
    margin-left: 12px;
    border-left: 2px solid currentColor;
    border-top: 2px solid currentColor;
    rotate: 45deg;
    translate: 0 3px;
    transition: rotate var(--dur-calm) var(--ease-out), translate var(--dur-calm) var(--ease-out);
  }
  .drawer[data-open="true"] .drawer-chevron { rotate: 225deg; translate: 0 -3px; }
  .drawer-handle-end { display: flex; align-items: center; }

  .drawer-body {
    display: grid;
    padding: 4px 20px 18px;
  }
  .drawer[data-open="false"] .drawer-body { visibility: hidden; transition: visibility 0s linear var(--dur-calm); }

  .shelf-row {
    display: grid;
    grid-template-columns: 112px minmax(0, 1fr);
    align-items: center;
    gap: 12px;
    min-height: 52px;
    border-bottom: 4px solid var(--wood);
    box-shadow: 0 2px 0 var(--ink);
    margin-bottom: 6px;
  }
  .shelf-row:last-child { margin-bottom: 0; }

  .shelf-toggle {
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: 44px;
    padding: 0 4px;
    border: 0;
    background: transparent;
    cursor: pointer;
    text-align: left;
  }
  .shelf-row .slider { height: 44px; }
}

/* An on/off pip, drawn: hollow when off, lamp-lit when on. */
.pip {
  flex: none;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  border: 1.5px solid var(--text-muted);
  transition: background-color var(--dur-quick) var(--ease-out), border-color var(--dur-quick) var(--ease-out);
}
[aria-pressed="true"] > .pip { background: var(--lamp); border-color: var(--lamp); }

@media (prefers-reduced-motion: reduce) {
  .scene { animation-duration: var(--dur-quick); }
  .tag { transition-property: opacity, visibility; }
  .drawer { transition: none; }
  .drawer-chevron { transition: none; }
}
