/* ==========================================================================
   Direction v2-01 — KILN  (winner; polished pass)
   Palette mined from the Clay design-system reference (popular-web-designs),
   then authored into a two-ink colour code:
     paper  #faf9f7  warm cream canvas (Clay: Warm Cream)
     oat    #dad4c8  primary border (Clay: Oat Border), light #eee9df
     ink    #000000  type (Clay: Clay Black) with #55534e / #6f6b63 shades
     short  #0089ad  Clay Slushie 800 family  -> 15-min ink
     long   #d08a11  Clay Lemon 700 family    -> 45-min ink
     hot    #fc7981  Clay Pomegranate 400     -> manual-override marker
   LIGHT is the landing theme and is unchanged from the picked round.
   DARK was reworked twice after Rashan's note ("flat/jarring"). First the page
   was lifted off near-black, because the hard offset shadows are pure black —
   on a #14120f page they were invisible, which is what read as "flat". Then
   the surface step was widened: page #241f18 -> card #3b3428 (~1.33:1
   luminance step) with a near-black shadow, so a card reads as a card against
   the page without soft shadows. Ink is a warm cream off-white (#e8e1d4,
   ~12:1 on the page instead of ~15.6:1) to kill glare on the big type blocks,
   and the two inks are lifted (Slushie/Lemon 500) with 15-min/45-min tints
   that sit above the page instead of reading as holes. Unselected day cells
   now clear 3.5:1 against the page (light theme: 1.4:1). Same two-ink code,
   same measured floors.
   Type: Gabarito (display) / Instrument Sans (body) / DM Mono (numbers).
   Squared throughout: no border-radius anywhere (the offset shadow, not a
   radius, is the depth cue). Spacing runs on a 4px scale (--sp-*).

   ROUND-3 FIX (Rashan's review of the polished round — held):
     1 padding — every surface moved onto a generous 4px rhythm: sheet 24 -> 32,
       card band 64 -> 76px tall, body blocks 12 -> 16/20, buttons 12 -> 17px
       vertical. No text sits inside 12px of a border anywhere.
     2 the "tick chosen" stamp is deleted. Selection reads from the card body
       filled solid with that duration's ink, the 3px offset shadow and the
       2px translate; the fill carries which duration is chosen, and
       aria-pressed carries it to AT.
     3 buttons are designed controls: display face, 16px/600, line-height 1.5,
       -0.01em tracking, 13px x 24px padding (Clay's button row on the 4px scale).
     4 every button changes COLOUR on hover — filled and outline swap roles,
       slot/day/card hover fills with a surface tint, inline link-buttons take
       a surface fill. No hover state that only moves.
     5 GSAP (core + timeline) drives the flow: staggered pane entrance, slot-grid
       reveal, duration-pick pulse, timezone-badge swap. Entrances still never
       fire on first paint, and gsap.matchMedia honours reduced motion.

   ROUND-4 FIX (Rashan, 2026-10-18 — "rethink the finishing and the palette usage"):
     6 the muted tiers are fewer and further apart. Dark used to carry three
       near-identical warm greys between the ink and the canvas, and two more
       that differed by 5%; `--hov` and `--oat2` are now ONE step, so a hairline
       and a hover fill are the same tone used two ways instead of two tones
       doing the same job.
     7 the loud accent fills are pulled back. On dark the two inks were 13.2:1
       and 14.0:1 against their own black text — brighter than the page's own
       primary ink, which is why a filled card shouted. They are 8.9:1 and
       9.5:1 now: still unmistakably a filled duration block, no longer the
       brightest thing on the page.
     8 unselected control borders clear the 3:1 non-text floor against the card
       they sit on, in both themes (`--oat`). The mock measured 1.48:1 in light
       and left it as a documented gap; the day grid is a control surface, so
       the gap is closed here rather than re-documented.
     9 the timezone chip's "auto-detected" state stops wearing the 45-minute
       amber. Colour on this page encodes duration and nothing else, so a state
       that is not a duration belongs to the `--ink` family — the "booked" badge
       already follows that rule. "set manually" keeps `--hot`, which is the one
       job that ink has.

   ROUND-4 THEME DEFAULT: no `data-theme` attribute means "follow the OS". The
   dark tokens are declared a second time inside a prefers-color-scheme block
   (see below) rather than shared, because CSS cannot apply one declaration block
   from a selector list when one entry needs a media query around it.
   ========================================================================== */
:root{
  /* spacing scale — 4px base, used for every gap/margin/padding in the sheet */
  --sp-1:4px; --sp-2:8px; --sp-3:12px; --sp-4:16px; --sp-5:20px; --sp-6:24px; --sp-7:32px;
  /* motion */
  --fast:120ms; --mid:180ms; --ease:cubic-bezier(.2,0,0,1);
  /* the two-ink palette */
  --paper:#faf9f7; --card:#ffffff;
  /* One step, two uses: the hairline inside a card and the hover fill on a
     neutral surface. They used to be 1.19:1 and 1.21:1 against the card — the
     same tone twice. (round 4) */
  --oat:#8a857c; --oat2:#eae4d8; --hov:#eae4d8;
  --ink:#000000; --ink2:#55534e; --ink3:#6f6b63;
  --short:#0089ad; --short-tint:#e3f5fa;
  --long:#d08a11; --long-tint:#fdf1dc;
  --hot:#fc7981; --err:#8f1d28;
  --pop:6px 6px 0 var(--ink);
  --pop-sm:3px 3px 0 var(--ink);
  --sans:'Instrument Sans',system-ui,-apple-system,'DejaVu Sans',sans-serif;
  --disp:'Gabarito','Instrument Sans',system-ui,sans-serif;
  --mono:'DM Mono',ui-monospace,Menlo,Consolas,monospace;
}
/* THEME DEFAULT (round 4). No `data-theme` attribute means "follow the OS" —
   the media query below supplies the dark tokens, so the correct theme is
   painted before any script runs and there is no flash to paper over with a
   cookie. `public/app.js` writes `data-theme` only when the visitor has made an
   explicit choice, and clearing that choice is how they get back to the OS. */
[data-theme="dark"]{
  --paper:#241f18; --card:#3b3428;
  /* oat2 and hov are one step: two tones 5% apart read as a mistake, not a
     system. (round 4) */
  --oat:#9a9080; --oat2:#4a4234; --hov:#4a4234;
  --ink:#e8e1d4; --ink2:#cfc5b2; --ink3:#b0a593;
  /* the two inks, pulled back from 13.2:1 / 14.0:1 to 8.9:1 / 9.5:1 against
     their own black text (measured; round 4) */
  --short:#4fb6cf; --short-tint:#17323b;
  --long:#d9a63e; --long-tint:#3f3218;
  --hot:#ffa8ac; --err:#ffb9bd;
  --pop:6px 6px 0 #0a0906; --pop-sm:3px 3px 0 #0a0906;
}
/* The OS default. Declared a second time rather than shared with the rule above
   because CSS has no way to apply one declaration block from two selectors when
   one of them needs a media query around it — and `light-dark()` would leave an
   older browser with no tokens at all. Two copies of eleven lines is the boring,
   universally-supported answer. `data-theme="light"` opts out. */
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]){
    --paper:#241f18; --card:#3b3428;
    --oat:#9a9080; --oat2:#4a4234; --hov:#4a4234;
    --ink:#e8e1d4; --ink2:#cfc5b2; --ink3:#b0a593;
    --short:#4fb6cf; --short-tint:#17323b;
    --long:#d9a63e; --long-tint:#3f3218;
    --hot:#ffa8ac; --err:#ffb9bd;
    --pop:6px 6px 0 #0a0906; --pop-sm:3px 3px 0 #0a0906;
  }
}
*{box-sizing:border-box}
html,body{margin:0}
body{background:var(--paper);color:var(--ink);font-family:var(--sans);font-size:16px;line-height:1.55;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-rendering:optimizeLegibility}
button{font:inherit;color:inherit}
.num{font-family:var(--mono);font-variant-numeric:tabular-nums}
:focus-visible{outline:3px solid var(--short);outline-offset:2px}
[data-theme="dark"] :focus-visible{outline-color:var(--short)}
.skip{position:absolute;left:-9999px}
.skip:focus{left:14px;top:14px;z-index:30;background:var(--card);color:var(--ink);padding:10px 14px;border:2px solid var(--ink);box-shadow:var(--pop-sm)}
.vh{position:absolute;width:1px;height:1px;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
[hidden]{display:none !important}

/* headings balance, body copy avoids orphans */
h1,h2,h3,.summary .what{text-wrap:balance}
.lede,.bio,.note,.fine,.err,.hint,.empty{text-wrap:pretty}

.wrap{max-width:1044px;margin:0 auto;padding:var(--sp-6) var(--sp-6) 88px}
/* wraps rather than squashing: the theme picker is three controls wide and the
   brand is not allowed to shrink to fit it (round 4) */
.topbar{display:flex;flex-wrap:wrap;justify-content:space-between;align-items:center;gap:var(--sp-3) var(--sp-4);padding-bottom:var(--sp-5)}
.brand{font-family:var(--disp);font-weight:700;font-size:15px;letter-spacing:.01em}
.brand em{font-style:normal;color:var(--ink3);font-weight:500}
/* Theme: an explicit three-state override (round 4). There is no icon pair any
   more — the state is a word, and a word cannot be misread. "System" is both the
   default and the way back to it: the OS decides until the visitor says
   otherwise, and the media query in this file already painted the right one.
   One control, three states, and clearing the stored choice is a button rather
   than a console instruction. */
.themepick{display:inline-flex;border:2px solid var(--ink);box-shadow:var(--pop-sm)}
.tpick{background:var(--card);color:var(--ink);border:0;padding:9px var(--sp-3);font-family:var(--disp);font-size:12.5px;font-weight:600;line-height:1.35;letter-spacing:-.005em;cursor:pointer;min-height:40px}
.tpick+.tpick{border-left:2px solid var(--ink)}
.tpick[aria-pressed="true"]{background:var(--ink);color:var(--paper)}
/* The only hover in the interface that must not lift: the three states are
   inside one frame, so moving one would move the frame. */
.tpick:hover:not([aria-pressed="true"]),.tpick:active{background:var(--ink);color:var(--paper)}

.stage{display:grid;grid-template-columns:minmax(0,318px) minmax(0,1fr);gap:var(--sp-6);align-items:start}

/* ---- left rail: host + the two inks ---- */
.rail{display:grid;gap:var(--sp-6);position:sticky;top:22px}
.host{background:var(--card);border:2px solid var(--ink);box-shadow:var(--pop);padding:var(--sp-6)}
/* The photo frame. Two states, one frame: the owner's uploaded image, or the
   initials as a quiet fallback. Nothing here says "placeholder" — a frame with
   initials in it is a designed state, not a hole waiting to be filled, and the
   dashboard is where the image comes from (settings.page_photo). */
.avatar{width:96px;height:96px;flex:none;border:2px solid var(--ink);background:var(--card);display:grid;place-items:center;overflow:hidden;margin-bottom:var(--sp-5)}
/* The initials and the image share the one cell, so the frame never reflows
   while the image decodes and neither state is ever an empty box. */
.avatar>*{grid-area:1/1}
.avatar .initials{font-family:var(--disp);font-weight:700;font-size:30px;line-height:1;letter-spacing:-.02em;color:var(--ink2)}
/* The image fills the frame and is cropped to it; the 1px outline is pure black
   at 10% (white in dark), never a tinted neutral — a tinted hairline picks up
   the surface underneath and reads as dirt on the edge
   (make-interfaces-feel-better · surfaces.md). */
.avatar img{width:100%;height:100%;object-fit:cover;display:block;background:var(--oat2);box-shadow:inset 0 0 0 1px rgba(0,0,0,.1)}
[data-theme="dark"] .avatar img{box-shadow:inset 0 0 0 1px rgba(255,255,255,.1)}
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]) .avatar img{box-shadow:inset 0 0 0 1px rgba(255,255,255,.1)}
}
.host h1{margin:0;font-family:var(--disp);font-weight:700;font-size:25px;line-height:1.1;letter-spacing:-.01em}
.host .bio{margin:var(--sp-2) 0 0;font-size:14px;color:var(--ink2)}

.ledger{background:var(--card);border:2px solid var(--ink);padding:var(--sp-6)}
.ledger h2{margin:0 0 var(--sp-2);font-family:var(--disp);font-size:15px;font-weight:700;letter-spacing:.02em;text-transform:uppercase}
.ledger p{margin:0 0 var(--sp-4);font-size:13px;color:var(--ink2)}
.keyrow{display:flex;align-items:center;gap:var(--sp-3);font-size:13.5px;padding:10px 0;border-top:1px solid var(--oat2)}
.keyrow:first-of-type{border-top:0}
.swatch{width:20px;height:20px;flex:none;border:2px solid var(--ink)}
.keyrow .dur{margin-left:auto;font-family:var(--mono);font-size:13px;font-variant-numeric:tabular-nums;color:var(--ink2)}
.facts{margin:var(--sp-4) 0 0;padding:0;list-style:none;font-size:12.5px;color:var(--ink2)}
.facts li{padding:6px 0 6px var(--sp-4);position:relative}
.facts li::before{content:"";position:absolute;left:0;top:12px;width:7px;height:7px;background:var(--ink)}

/* ---- right: the sheet ---- */
.sheet{background:var(--card);border:2px solid var(--ink);box-shadow:var(--pop);padding:var(--sp-7)}
.sheet h2{margin:0;font-family:var(--disp);font-weight:700;font-size:27px;line-height:1.12;letter-spacing:-.015em}
.lede{margin:var(--sp-3) 0 var(--sp-6);color:var(--ink2);font-size:14.5px;line-height:1.55;max-width:56ch}

.sizes{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-4)}
.size{position:relative;text-align:left;background:var(--card);border:2px solid var(--ink);padding:0;cursor:pointer;overflow:hidden}
.size .band{height:76px;border-bottom:2px solid var(--ink);display:flex;align-items:center;justify-content:space-between;gap:var(--sp-3);padding:0 var(--sp-4);color:#000}
.size.s-short .band{background:var(--short)}
.size.s-long .band{background:var(--long)}
.size .band b{font-family:var(--disp);font-weight:700;font-size:24px;line-height:1}
.size .band .mins{font-family:var(--mono);font-size:12px;line-height:1.3;text-align:right;font-variant-numeric:tabular-nums}
/* display:block matters — as an inline span the vertical padding was ignored and
   the selected-state tint would paint fragments instead of the card body */
.size .body{display:block;padding:var(--sp-4) var(--sp-4) var(--sp-5)}
.size .body strong{display:block;font-family:var(--disp);font-size:19px;font-weight:600;line-height:1.25}
.size .body span{display:block;margin-top:var(--sp-2);font-size:13.5px;line-height:1.5;color:var(--ink2)}
.size[aria-pressed="true"]{box-shadow:var(--pop-sm);transform:translate(2px,2px)}
/* ROUND-3: the "tick chosen" stamp is gone (Rashan). The chosen state is the
   card's own ink, in the solid form the selected slot chip already uses: the
   body fills with the duration ink, the text flips to black, the 3px offset
   shadow appears and the card settles 2px into it. A pale tint alone read as
   too weak to carry the state in the light theme. */
.size.s-short[aria-pressed="true"] .body{background:var(--short)}
.size.s-long[aria-pressed="true"] .body{background:var(--long)}
.size[aria-pressed="true"] .body,.size[aria-pressed="true"] .body span{color:#000}

.actions{display:flex;align-items:center;gap:var(--sp-4);margin-top:var(--sp-7);flex-wrap:wrap}
/* buttons are designed controls, not default text in a box. Metrics follow the
   Clay reference's button row (16px UI size, weight for the display face,
   line-height 1.5, slightly negative tracking) on this file's 4px padding scale. */
.btn{background:var(--ink);color:var(--paper);border:2px solid var(--ink);padding:13px var(--sp-6);font-family:var(--disp);font-size:16px;font-weight:600;line-height:1.5;letter-spacing:-.01em;cursor:pointer}
.btn.ghost{background:var(--card);color:var(--ink)}
/* every button changes COLOUR on hover: the filled and the outline swap roles */
.btn:hover:not(:disabled){background:var(--card);color:var(--ink)}
.btn.ghost:hover:not(:disabled){background:var(--ink);color:var(--paper)}
/* A disabled control has to LOOK refused: the label said "Saved" for a tenth of a
   second and the button never moved, so it read as still-pressable. The .72 is
   the busy value below — the same "not now" at the same weight. */
.btn:disabled{cursor:not-allowed;opacity:.72}
.btn[aria-busy="true"]{cursor:progress;opacity:.72}
/* Secondary copy: the tier for sentences. `--ink3` below is for micro labels and
   disabled text only — round 4 unified the two, because `.fine` and `.hint` were
   sentences wearing the label tier and read as an afterthought (5.06:1) next to
   the body copy (7.19:1). */
.fine{font-size:12.5px;color:var(--ink2);margin:var(--sp-4) 0 0}

/* ---- timezone bar ---- */
.tzbar{display:flex;flex-wrap:wrap;align-items:center;gap:var(--sp-2) var(--sp-4);background:var(--short-tint);border:2px solid var(--ink);padding:var(--sp-4);margin-bottom:var(--sp-6)}
.tzbar .lbl{font-size:13px;font-weight:600}
.tzbar select{font:inherit;font-size:13.5px;background:var(--card);color:var(--ink);border:2px solid var(--ink);padding:8px var(--sp-3);max-width:100%;min-height:40px}
.tzbar .off{font-family:var(--mono);font-variant-numeric:tabular-nums;font-size:13px;padding-left:2px}
/* A state chip. The ink family carries state; the two duration inks carry
   duration and nothing else. "auto-detected" is the normal state, so it is the
   quiet one; "set manually" is the exception and keeps `--hot` — the one job
   that ink has (round 4: auto used to wear the 45-minute amber). */
.chip{display:inline-block;font-size:10.5px;font-weight:700;letter-spacing:.09em;text-transform:uppercase;padding:4px var(--sp-2) 3px;border:2px solid var(--ink);background:var(--card);color:var(--ink);cursor:default}
.chip.manual{background:var(--hot);color:#000}
/* The inline link-button. Styled HERE and unscoped because it had been written
   as `.tzbar .reset`, which styled exactly one of its call sites: the dashboard's
   Availability editor ("remove", "add hours") and its topbar link matched
   nothing and fell back to browser button chrome, which is the grey-on-grey
   Rashan screenshotted (round 4). One class, one look, everywhere it is used. */
.reset{background:none;border:0;padding:9px var(--sp-2);min-height:40px;font:inherit;font-size:12.5px;font-weight:600;color:var(--ink2);text-decoration:underline;text-underline-offset:2px;cursor:pointer}
.reset:hover{color:var(--ink);background:var(--hov)}
.reset:active{transform:scale(.96)}

/* ---- 14-day rail ---- */
.railhead{display:flex;justify-content:space-between;align-items:baseline;gap:var(--sp-3);margin:0 0 var(--sp-3)}
.railhead h3{margin:0;font-family:var(--disp);font-size:13px;font-weight:700;text-transform:uppercase;letter-spacing:.04em}
/* fortnight layout: all 14 days visible at once on desktop — 2 rows of 7 */
.days{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:var(--sp-2);padding:var(--sp-1);margin-bottom:var(--sp-6)}
.day{background:var(--card);border:2px solid var(--oat);padding:10px var(--sp-2);text-align:center;cursor:pointer;min-width:0}
.day:hover:not([aria-pressed="true"]):not(:disabled){border-color:var(--ink);background:var(--hov)}
/* the hover surface is not the card surface: lift the micro label off --ink3 so
   it stays above AA on the hover fill (measured 4.47:1 before this) */
.day:hover:not([aria-pressed="true"]):not(:disabled) .dw{color:var(--ink)}
.day[aria-pressed="true"]{background:var(--ink);border-color:var(--ink);color:var(--paper)}
.day:disabled{opacity:.55;cursor:not-allowed;border-style:dashed}
.day .dw{display:block;font-size:10.5px;font-weight:600;letter-spacing:.09em;text-transform:uppercase;color:var(--ink3);white-space:nowrap;overflow:hidden}
.day[aria-pressed="true"] .dw{color:var(--paper)}
.day .dn{display:block;font-family:var(--mono);font-size:20px;line-height:1.25}
.day .dc{display:block;font-size:11px;color:var(--ink2);font-variant-numeric:tabular-nums}
.day[aria-pressed="true"] .dc{color:var(--paper)}
.day .today{display:block;font-size:9.5px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--err)}
.day[aria-pressed="true"] .today{color:var(--paper)}

/* ---- slots ---- */
.part{margin-bottom:var(--sp-5)}
.part h4{margin:0 0 var(--sp-3);font-size:12px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--ink3);border-bottom:1px solid var(--oat2);padding-bottom:var(--sp-2)}
.slots{display:flex;flex-wrap:wrap;gap:var(--sp-2)}
.slot{border:2px solid var(--ink);background:var(--card);padding:12px var(--sp-4);font-family:var(--mono);font-size:14.5px;font-variant-numeric:tabular-nums;cursor:pointer;display:flex;align-items:center;gap:var(--sp-3)}
.slot .tick{width:6px;height:18px;flex:none;background:var(--short)}
.slot.long .tick{background:var(--long)}
/* hover = this slot's ink in tint form, plus the lift */
.slot:hover:not([aria-pressed="true"]):not(:disabled){box-shadow:var(--pop-sm);background:var(--short-tint)}
.slot.long:hover:not([aria-pressed="true"]):not(:disabled){background:var(--long-tint)}
.slot[aria-pressed="true"]{background:var(--short);color:#000}
.slot.long[aria-pressed="true"]{background:var(--long);color:#000}
/* once the slot is filled with its own ink the tick would vanish — keep a black
   bar, which reads on every pressed fill in both themes */
.slot[aria-pressed="true"] .tick{background:#000}
.slot:disabled{border-style:dashed;border-color:var(--oat);color:var(--ink3);text-decoration:line-through;cursor:not-allowed}
.slot:disabled .tick{background:var(--ink3)}
.empty{font-size:14px;color:var(--ink2)}
/* a sentence, so the secondary tier (see `.fine`) */
.hint{font-size:12.5px;color:var(--ink2);margin:var(--sp-4) 0 0}
.legend{display:flex;gap:var(--sp-5);flex-wrap:wrap;font-size:12px;color:var(--ink2);margin:0 0 var(--sp-6)}
.legend i{display:inline-block;width:10px;height:10px;margin-right:6px;border:2px solid var(--ink)}
.legend i.gap{background:transparent;border-style:dashed;border-color:var(--ink3)}

/* ---- details ---- */
/* the strip echoes the CHOSEN duration's ink. A fixed amber strip said "45 min"
   over a Short booking, which breaks the page's own "colour encodes duration"
   rule — so the tint follows the choice (base amber kept as the fallback). */
.summary{border:2px solid var(--ink);background:var(--long-tint);padding:var(--sp-5);margin-bottom:var(--sp-6);display:flex;flex-wrap:wrap;gap:var(--sp-2) var(--sp-5);align-items:baseline;justify-content:space-between}
.summary.ink-short{background:var(--short-tint)}
.summary.ink-long{background:var(--long-tint)}
.summary .what{font-family:var(--disp);font-weight:700;font-size:17px}
.summary .when{font-size:13.5px;color:var(--ink2)}
.summary .when b{color:var(--ink);font-family:var(--mono);font-size:13.5px;font-variant-numeric:tabular-nums}
.summary .when .num{color:var(--ink)}
.summary button{background:none;border:0;padding:9px var(--sp-2);min-height:40px;font-size:13px;font-weight:600;color:var(--ink2);text-decoration:underline;cursor:pointer}
.fields{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-5)}
.field{display:flex;flex-direction:column;gap:var(--sp-2)}
.field.wide{grid-column:1/-1}
label{font-size:12.5px;font-weight:600;color:var(--ink2)}
label .opt{font-weight:400;color:var(--ink3)}
input,textarea{font:inherit;font-size:15.5px;padding:14px var(--sp-4);border:2px solid var(--ink);background:var(--card);color:var(--ink)}
textarea{min-height:86px;resize:vertical}
input[aria-invalid="true"]{border-color:var(--err);background:#fdeeee}
[data-theme="dark"] input[aria-invalid="true"]{background:#402228}
.err{font-size:12.5px;color:var(--err);font-weight:500}

/* ---- confirmed ---- */
.done h2{font-size:30px}
.done .range{margin:var(--sp-5) 0 var(--sp-2);font-family:var(--mono);font-size:22px;font-variant-numeric:tabular-nums}
.done .zone{font-size:13px;color:var(--ink2);letter-spacing:.02em}
.done .note{font-size:14px;line-height:1.6;color:var(--ink2);margin:var(--sp-4) 0 0;max-width:52ch}
.done .links{display:flex;gap:var(--sp-5);margin-top:var(--sp-6);font-size:13.5px;flex-wrap:wrap}
.done .links button{background:none;border:0;padding:9px var(--sp-2);min-height:40px;font-size:13.5px;font-weight:600;color:var(--ink2);text-decoration:underline;cursor:pointer}
/* status mark, not a duration mark — the "booked" badge must not wear the
   15-min ink (same rule the summary strip follows) */
.stamp{display:inline-block;font-family:var(--mono);font-size:11px;letter-spacing:.1em;text-transform:uppercase;background:var(--ink);color:var(--paper);border:2px solid var(--ink);padding:5px var(--sp-3);margin-bottom:var(--sp-4)}

/* interactive state changes are CSS transitions (interruptible).
   Hover = the surface/ink changes AND the offset shadow appears; press = the
   object settles flat into that shadow. GSAP owns only the staged entrances
   (pane + slot-grid reveals, one selection pulse), because those need
   sequencing; it never touches a property a CSS transition owns. */
@media (prefers-reduced-motion:no-preference){
  .size,.slot,.btn,.day,.tpick,.reset{transition:box-shadow var(--fast) var(--ease),transform var(--fast) var(--ease),background-color var(--fast) var(--ease),border-color var(--fast) var(--ease),color var(--fast) var(--ease)}
  .size .body{transition:background-color var(--fast) var(--ease)}
  /* CSS fallback for the staged entrance — used only when GSAP is not loaded.
     On a step change, never on first paint. */
  .sheet.rise{animation:ink var(--mid) var(--ease) both}
  @keyframes ink{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}
}
/* While a GSAP reveal owns an element, the CSS transitions on it and its
   subtree are switched off so the two systems never smooth the same property
   (see ownTransitions() in the script). */
.gsap-run,.gsap-run *{transition:none !important}
.btn:hover:not(:disabled){transform:translate(-2px,-2px);box-shadow:var(--pop-sm)}
.btn:active:not(:disabled){transform:translate(2px,2px);box-shadow:none}
.size:hover:not([aria-pressed="true"]){box-shadow:var(--pop-sm)}
.size:hover:not([aria-pressed="true"]) .body{background:var(--hov)}
.size:active{transform:translate(3px,3px);box-shadow:none}
.day:active:not(:disabled){transform:scale(.96)}
/* inline link-buttons: a colour change plus a surface fill, never motion-only */
.summary button:hover,.done .links button:hover{color:var(--ink);background:var(--hov)}
.skip:hover{background:var(--ink);color:var(--paper)}
.summary button:active,.done .links button:active{transform:scale(.96)}

@media (max-width:920px){
  .stage{grid-template-columns:1fr}
  .rail{position:static;grid-template-columns:1fr}
}
@media (max-width:620px){
  .wrap{padding:var(--sp-5) var(--sp-4) 64px}
  .sheet{padding:var(--sp-5)}
  .host,.ledger{padding:var(--sp-5)}
  .sheet h2{font-size:22px}
  .lede{margin-bottom:var(--sp-5)}
  .sizes{grid-template-columns:1fr}
  .fields{grid-template-columns:1fr}
  .host h1{font-size:22px}
  /* keep all 14 days on screen without sideways scrolling */
  .days{grid-template-columns:repeat(4,minmax(0,1fr))}
  .slot{flex:1 1 45%;justify-content:flex-start}
  .done .range{font-size:19px}
  /* touch context: the 40px desktop floor becomes the 44px touch target */
  .tpick,.reset,.summary button,.done .links button{min-height:44px}
}
