/* ==========================================================================
   NRC PROTOTYPE — Quest / Food / Move / Me
   Design system from Jason's approved sheets (nrc imgs/web app graphics/,
   2026-08-26 22:11). Every hex below is quoted from the palette block on that
   sheet — none of it is interpretation.

   CLERK DENSITY (Jason's ruling): BIG on the moments where the Clerk is the
   content — Quest, completions, empty states, errors. SMALL badge in the header
   band on working screens, so the primary action is never pushed below the fold.

   Type scale is in rem so system font scaling works. Nothing is set in px.
   ========================================================================== */

:root{
  /* --- the approved palette ------------------------------------------- */
  --coral:#FF4B28;      /* PRIMARY. Act. */
  --red:#A92D26;        /* deep red — headers, stamps */
  --olive:#83952F;      /* SECONDARY */
  --mustard:#FFC233;    /* highlight, never a surface */
  --teal:#0E8C8B;       /* movement, calm sections */
  --cream:#FFF4DE;      /* the ground */
  --charcoal:#102027;   /* ink + tab bar */
  --white:#FFFFFF;

  /* derived, used sparingly */
  --cream-2:#F6E8CB;    /* recessed rows */
  --cream-3:#EFDDBB;    /* tertiary buttons */
  --ink:var(--charcoal);
  --ink-2:#3E4B52;
  /* 5.71:1 on cream, up from 4.43:1 — #6B7378 sat under WCAG AA on the one
     background this app uses most. Same grey to look at, and no surface
     regresses (Naomi 2026-09-08). It fixes CONTRAST, not SIZE: .qdot span and
     .qstep .st span are still under the legibility floor for a 35-65 reader
     and are a separate open item. */
  --ink-3:#5A6266;
  --line:#E2D2AF;

  --body:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;

  --t-hero:2.15rem; --t-h1:1.5rem; --t-h2:1.15rem;
  --t-body:1.0625rem; --t-sub:.95rem; --t-label:.72rem;

  --tap:3.5rem;
  --gut:1.05rem;
  --r:1rem;
  --tabbar:4.5rem;
  --safe-b:env(safe-area-inset-bottom,0px);
  --safe-t:env(safe-area-inset-top,0px);
}

*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}
html,body{margin:0;padding:0;min-height:100%}
body{
  background:var(--cream); color:var(--ink);
  font:var(--t-body)/1.5 var(--body);
  -webkit-font-smoothing:antialiased; overscroll-behavior-y:none;
}
button{font:inherit;color:inherit;border:0;background:none;cursor:pointer;text-align:left}
input,textarea{font:inherit;color:inherit}
:focus-visible{outline:3px solid var(--coral);outline-offset:2px;border-radius:.4rem}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}

/* ── shell ──────────────────────────────────────────────────────────────── */
/* +2px so the settle-nudge scroll (app.js settleViewport) always has room to
   move even on short screens — invisible, but iOS needs a real scroll */
.app{min-height:calc(100dvh + 2px);display:flex;flex-direction:column;
  padding-bottom:calc(var(--tabbar) + var(--safe-b))}
.screen{flex:1;display:flex;flex-direction:column}
.screen[hidden]{display:none}
.pad{padding:1rem var(--gut) 2rem;display:flex;flex-direction:column;gap:.85rem}

/* ── HEADER — plain, quiet, on the page's own ground (Jason 2026-08-27:
   the coloured scalloped band + the Percy circle badge are gone) ─────────── */
.band{
  position:relative;background:var(--cream);color:var(--ink);
  padding:calc(var(--safe-t) + 1.9rem) var(--gut) .4rem;
  display:flex;align-items:center;gap:.7rem;
}
.band--coral,.band--olive,.band--teal,.band--red{background:var(--cream)}
.band h1{margin:0;font-size:var(--t-h2);font-weight:900;letter-spacing:.02em;
  text-transform:uppercase;flex:1;line-height:1.15}
.band .backbtn{
  width:2.5rem;height:2.5rem;min-width:2.5rem;border-radius:999px;
  background:var(--white);border:2px solid var(--line);display:grid;place-items:center;
  font-size:1.3rem;font-weight:800;line-height:1;color:var(--ink);
}

/* ── type ───────────────────────────────────────────────────────────────── */
.eyebrow{font-size:var(--t-label);letter-spacing:.14em;text-transform:uppercase;
  color:var(--red);font-weight:900;margin:0}
.hero{margin:0;font-size:var(--t-hero);line-height:1.06;letter-spacing:-.02em;
  font-weight:900;text-transform:uppercase}
.hero .hot{color:var(--coral)}
.lede{margin:0;color:var(--ink-2)}
h2.sect{margin:1.2rem 0 -.15rem;font-size:var(--t-label);letter-spacing:.14em;
  text-transform:uppercase;color:var(--ink-3);font-weight:900}

/* ── buttons — primary / secondary / tertiary / ghost ───────────────────── */
.btn{display:flex;align-items:center;justify-content:center;gap:.5rem;width:100%;
  min-height:var(--tap);padding:.9rem 1.1rem;border-radius:.85rem;
  font-size:var(--t-body);font-weight:900;letter-spacing:.02em;
  background:var(--coral);color:var(--white);
  box-shadow:0 3px 0 rgba(16,32,39,.22);
}
.btn:active{transform:translateY(2px);box-shadow:0 1px 0 rgba(16,32,39,.22)}
.btn--secondary{background:var(--olive)}
.btn--tertiary{background:var(--cream-3);color:var(--ink);box-shadow:0 3px 0 rgba(16,32,39,.12)}
.btn--teal{background:var(--teal)}
.btn--ghost{background:transparent;color:var(--ink-2);border:2px dashed var(--line);
  box-shadow:none;font-weight:800}
.btn--link{background:none;box-shadow:none;color:var(--red);text-decoration:underline;
  font-weight:800;min-height:2.75rem}
.btn[disabled]{opacity:.5}

/* ── cards ──────────────────────────────────────────────────────────────── */
.card{background:var(--white);border:1px solid var(--line);border-radius:var(--r);
  padding:1rem;box-shadow:0 2px 0 rgba(16,32,39,.07)}
.tapcard{display:flex;align-items:center;gap:.85rem;width:100%;min-height:var(--tap);
  background:var(--white);border:1px solid var(--line);border-radius:var(--r);
  padding:.85rem .95rem;box-shadow:0 2px 0 rgba(16,32,39,.07)}
.tapcard:active{transform:translateY(1px);box-shadow:none}
.tapcard .ic{flex:none;width:2.9rem;height:2.9rem;border-radius:999px;
  display:grid;place-items:center;font-size:1.35rem;background:var(--cream-2);position:relative}
.tapcard .ic--coral{background:var(--coral)} .tapcard .ic--olive{background:var(--olive)}
.tapcard .ic--mustard{background:var(--mustard)} .tapcard .ic--teal{background:var(--teal)}
.tapcard .ic--charcoal{background:var(--charcoal)}
.tapcard .tx{flex:1;min-width:0}
.tapcard .tt{display:block;font-weight:900;font-size:var(--t-h2);line-height:1.25}
.tapcard .ts{display:block;color:var(--ink-3);font-size:var(--t-sub);margin-top:.1rem}
.tapcard .go{flex:none;font-size:1.2rem;color:var(--ink-3);font-weight:800}
.tapcard--off{opacity:.8}
.tapcard--off .go{font-size:var(--t-label);letter-spacing:.08em;text-transform:uppercase;
  font-weight:900;color:var(--red)}
.soon{position:absolute;bottom:-.25rem;left:50%;transform:translateX(-50%);
  background:var(--red);color:var(--white);font-size:.5rem;font-weight:900;
  letter-spacing:.06em;padding:.1rem .3rem;border-radius:.2rem;text-transform:uppercase}
.stack{display:flex;flex-direction:column;gap:.65rem}
.row{display:flex;gap:.5rem;flex-wrap:wrap}

/* ── chips ──────────────────────────────────────────────────────────────── */
.chip{min-height:3rem;padding:.6rem 1rem;border-radius:999px;background:var(--white);
  border:2px solid var(--line);font-weight:800;font-size:var(--t-sub)}
.chip[aria-pressed="true"]{background:var(--charcoal);color:var(--cream);border-color:var(--charcoal)}

/* ── KEEP / CHANGE / ADD — the answer shape from the sheet ─────────────── */
.kca{display:flex;flex-direction:column;gap:.5rem;margin-top:.9rem}
.kca-row{display:flex;gap:.75rem;align-items:flex-start;background:var(--white);
  border:1px solid var(--line);border-radius:.75rem;padding:.75rem .85rem}
.kca-tag{flex:none;display:flex;align-items:center;gap:.4rem;font-weight:900;
  font-size:var(--t-sub);letter-spacing:.04em;text-transform:uppercase;min-width:5.6rem}
.kca-dot{width:1.4rem;height:1.4rem;border-radius:999px;display:grid;place-items:center;
  color:var(--white);font-size:.8rem;font-weight:900}
.kca--keep .kca-dot{background:var(--olive)} .kca--keep .kca-tag{color:var(--olive)}
.kca--change .kca-dot{background:var(--mustard);color:var(--charcoal)} .kca--change .kca-tag{color:#8A6A00}
.kca--add .kca-dot{background:var(--teal)} .kca--add .kca-tag{color:var(--teal)}
.kca-txt{flex:1;color:var(--ink-2);font-size:var(--t-sub);line-height:1.4}

/* ── decision card ──────────────────────────────────────────────────────── */
.dc{background:var(--white);border:1px solid var(--line);border-radius:var(--r);
  padding:1rem;box-shadow:0 2px 0 rgba(16,32,39,.07)}
.dc-top{display:flex;align-items:flex-start;gap:.6rem;justify-content:space-between}
.dc-name{margin:0;font-size:var(--t-h1);font-weight:900;line-height:1.15}
.dc-chip{flex:none;font-size:var(--t-label);font-weight:900;letter-spacing:.05em;
  text-transform:uppercase;padding:.35rem .6rem;border-radius:.4rem;
  background:var(--olive);color:var(--white)}
.dc-chip.tweak{background:var(--mustard);color:var(--charcoal)}
.dc-chip.think{background:var(--coral);color:var(--white)}
.dc-sum{margin:.5rem 0 0;color:var(--ink-2)}
.dc-h{margin:.9rem 0 .3rem;font-size:var(--t-label);letter-spacing:.12em;
  text-transform:uppercase;color:var(--ink-3);font-weight:900}
.dc ul{margin:0;padding-left:1.1rem}.dc li{margin:.25rem 0;color:var(--ink-2)}
.dc-meta{display:flex;gap:.35rem;flex-wrap:wrap;margin-top:.55rem}
.dc-tag{font-size:var(--t-label);font-weight:800;background:var(--cream-2);
  border-radius:999px;padding:.3rem .55rem}
.factrow{display:flex;gap:.6rem;align-items:center;padding:.45rem 0;
  border-bottom:1px solid var(--line);font-size:var(--t-sub)}
.factrow:last-child{border-bottom:0}
.factrow b{margin-left:auto;font-weight:900}

/* ── WHY — education inside the decision ────────────────────────────────── */
details.why{margin-top:.8rem;border-top:1px solid var(--line);padding-top:.5rem}
details.why summary{list-style:none;font-weight:900;color:var(--red);
  min-height:2.75rem;display:flex;align-items:center;cursor:pointer}
details.why summary::-webkit-details-marker{display:none}
details.why p{margin:.2rem 0 .5rem;color:var(--ink-2)}

/* ── STAMPS ─────────────────────────────────────────────────────────────── */
.stamp{display:inline-block;font-size:1.05rem;font-weight:900;letter-spacing:.08em;
  text-transform:uppercase;padding:.4rem .8rem;border:3px solid currentColor;
  border-radius:.3rem;transform:rotate(-6deg);color:var(--coral)}
.stamp--done{color:var(--olive)} .stamp--filed{color:var(--teal)}
.stamp--closed{color:var(--red)}

/* ── ILLUSTRATION SLOTS ─────────────────────────────────────────────────── */
.clerkbig{width:100%;aspect-ratio:16/11;border:2px dashed var(--line);border-radius:var(--r);
  background:var(--cream-2);display:grid;place-items:center;text-align:center;
  color:var(--ink-3);font-size:var(--t-label);letter-spacing:.1em;text-transform:uppercase;
  font-weight:900;padding:1rem}
.artslot{width:100%;aspect-ratio:16/9;border:2px dashed var(--line);border-radius:var(--r);
  background:var(--cream-2);display:grid;place-items:center;text-align:center;
  color:var(--ink-3);font-size:var(--t-label);letter-spacing:.1em;text-transform:uppercase;
  font-weight:900;padding:1rem}
.artslot--sq{aspect-ratio:1/1;max-width:7.5rem;margin:0 auto}

/* ── states ─────────────────────────────────────────────────────────────── */
.state{text-align:center;padding:1.4rem .5rem;display:flex;flex-direction:column;
  gap:.85rem;align-items:center}
.state h3{margin:0;font-size:var(--t-h1);font-weight:900;text-transform:uppercase}
.state p{margin:0;color:var(--ink-2);max-width:30rem}
.proto{display:inline-block;font-size:var(--t-label);font-weight:900;letter-spacing:.1em;
  text-transform:uppercase;color:var(--red);border:2px solid var(--red);
  border-radius:.3rem;padding:.25rem .5rem}
.spin{width:1.6rem;height:1.6rem;border:3px solid var(--line);border-top-color:var(--coral);
  border-radius:50%;animation:sp .8s linear infinite;margin:0 auto}
@keyframes sp{to{transform:rotate(360deg)}}

/* Percy waiting on something real. The bar sweeps (unknown duration) — only
   the boot splash claims a percentage, because only it knows one. */
.pwait{text-align:center;padding:1.2rem .5rem;display:flex;flex-direction:column;
  gap:.9rem;align-items:center}
.pwait-art{width:min(46vw,11rem);display:block;
  animation:pwin .5s cubic-bezier(.2,.9,.3,1.2) both,pwbob 3.2s ease-in-out .6s infinite}
.pwait-line{margin:0;color:var(--ink-2);max-width:30rem;font-weight:700}
.pbar{width:min(58vw,14rem);height:.85rem;box-sizing:border-box;overflow:hidden;
  border:2.5px solid var(--charcoal);border-radius:999px;background:var(--white)}
.pbar i{display:block;width:40%;height:100%;border-radius:999px;background:var(--olive);
  animation:pbsweep 1.25s cubic-bezier(.5,0,.5,1) infinite}
@keyframes pwin{from{opacity:0;transform:translateY(-10px) scale(.92)}to{opacity:1;transform:none}}
@keyframes pwbob{50%{transform:translateY(-6px)}}
@keyframes pbsweep{from{transform:translateX(-105%)}to{transform:translateX(255%)}}
@keyframes pbpulse{50%{opacity:.3}}
@media (prefers-reduced-motion:reduce){
  /* The sweep slides, which is the very thing reduced motion asks us to drop.
     But a frozen bar looks hung, so it goes full width and breathes instead:
     still says "working", with no movement to trigger anyone. */
  .pbar i{width:100%;animation:pbpulse 1.8s ease-in-out infinite !important}
}

/* ── step flow ──────────────────────────────────────────────────────────── */
.stepwrap{display:flex;flex-direction:column;gap:.85rem;flex:1}
.stepcount{font-size:var(--t-label);letter-spacing:.14em;text-transform:uppercase;
  color:var(--ink-3);font-weight:900}
.reps{font-size:1.5rem;font-weight:900;color:var(--olive)}
.steptext{font-size:1.2rem;line-height:1.45;margin:0;font-weight:600}
.stepnav{display:flex;gap:.5rem;margin-top:auto}
.stepnav .btn{flex:1}

/* ── lists ──────────────────────────────────────────────────────────────── */
.list{display:flex;flex-direction:column;gap:.4rem}
.li{display:flex;gap:.7rem;align-items:baseline;background:var(--white);
  border:1px solid var(--line);border-radius:.65rem;padding:.7rem .85rem}
.li b{font-weight:900}
.li .when{margin-left:auto;color:var(--ink-3);font-size:var(--t-sub);white-space:nowrap}

.foot{color:var(--ink-3);font-size:var(--t-sub);text-align:center;margin-top:1.2rem;line-height:1.45}
.demo{display:block;text-align:center;font-size:var(--t-label);letter-spacing:.08em;
  text-transform:uppercase;font-weight:900;color:var(--ink-3);
  background:var(--cream-2);padding:.4rem;border-bottom:1px solid var(--line)}

/* ── tab bar ────────────────────────────────────────────────────────────── */
.tabbar{position:fixed;left:0;right:0;bottom:0;z-index:30;
  /* auto columns, so adding a room does not need a number changing here */
  display:grid;grid-auto-flow:column;grid-auto-columns:1fr;
  background:var(--charcoal);padding-bottom:var(--safe-b)}
.tab{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.15rem;
  min-height:var(--tabbar);color:var(--cream);opacity:.68}
.tab[aria-current="page"]{color:var(--coral);opacity:1}
.tab svg{width:1.45rem;height:1.45rem;fill:currentColor}
.tab span{font-size:var(--t-label);font-weight:900;letter-spacing:.06em}

.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%)}

/* ══════════════════════════════════════════════════════════════════════════
   ILLUSTRATED TREATMENT
   Jason's ruling: the app looks like the reference — fully illustrated, not
   clean UI with icons bolted on. Artwork is cut from the approved sheets and
   lives in proto/art/.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── the stamp badge in the top bar ────────────────────────────────────── */
.topstamp{
  display:flex;align-items:center;justify-content:space-between;gap:.6rem;
  padding:calc(var(--safe-t) + 1.9rem) var(--gut) .2rem;background:var(--cream);
}
.topstamp .circ{
  width:2.75rem;height:2.75rem;min-width:2.75rem;border-radius:999px;
  background:var(--cream-3);display:grid;place-items:center;
  font-size:1.3rem;font-weight:900;line-height:1;color:var(--charcoal);
}
.topstamp .mark{
  border:2.5px solid var(--coral);border-radius:.35rem;padding:.25rem .7rem;
  text-align:center;transform:rotate(-1.2deg);line-height:1.05;
}
.topstamp .mark b{display:block;color:var(--coral);font-size:1.15rem;font-weight:900;letter-spacing:.05em}
.topstamp .mark span{display:block;color:var(--coral);font-size:.55rem;font-weight:800;letter-spacing:.06em}

/* ── the hero: display type left, clerk right, desk running underneath ─── */
.scene{position:relative;padding:.2rem 0 0}
.scene-txt{padding:0 var(--gut);position:relative;z-index:3;width:64%}
.scene-txt .hero{font-size:clamp(2.2rem,10.5vw,3rem);line-height:.95;letter-spacing:-.03em;
  transform:rotate(-1.5deg);transform-origin:left center}
.scene-txt .hand{margin:.9rem 0 0;font-size:1rem;line-height:1.35;color:var(--olive);
  font-style:italic;font-weight:600}
.scene-txt .hand u{text-decoration-color:var(--olive);text-underline-offset:.2rem}
.scene-clerk{position:absolute;right:-4%;top:.5rem;width:52%;z-index:2}
.scene-clerk img{width:100%;display:block}
.scene-desk{position:relative;z-index:1;margin-top:-1.5rem;width:100%;display:block}
.scene-desk img{width:100%;display:block}

/* ── the big coloured action card, artwork bleeding off the right ──────── */
.act{position:relative;display:flex;align-items:center;width:100%;min-height:7rem;
  border-radius:1.1rem;overflow:hidden;background:var(--olive);
  box-shadow:0 3px 0 rgba(16,32,39,.18)}
.act:active{transform:translateY(2px);box-shadow:0 1px 0 rgba(16,32,39,.18)}
.act--olive{background:var(--olive)} .act--coral{background:var(--coral)}
.act--amber{background:var(--mustard)}
.act-body{position:relative;z-index:2;display:flex;align-items:center;gap:.8rem;
  padding:1rem .9rem;width:68%}
.act-ic{flex:none;width:3.4rem;height:3.4rem;border-radius:999px;background:var(--cream);
  display:grid;place-items:center;overflow:hidden}
.act-ic img{width:100%;height:100%;object-fit:cover}
.act-tx{flex:1;min-width:0}
.act-tt{display:block;font-size:1.3rem;font-weight:900;line-height:1.05;
  text-transform:uppercase;letter-spacing:-.01em;color:var(--white)}
.act-ts{display:block;font-size:.9rem;line-height:1.25;margin-top:.2rem;color:rgba(255,255,255,.95)}
.act--amber .act-tt,.act--amber .act-ts{color:var(--charcoal)}
.act-go{flex:none;width:2.6rem;height:2.6rem;border-radius:999px;background:var(--charcoal);
  color:var(--white);display:grid;place-items:center;font-size:1.15rem;font-weight:900}
.act-art{position:absolute;right:0;top:0;bottom:0;width:44%;z-index:1}
.act-art img{width:100%;height:100%;object-fit:cover;object-position:left center}
.act--off{opacity:.9}
.act-soon{position:absolute;top:.5rem;right:.5rem;z-index:3;background:var(--charcoal);
  color:var(--white);font-size:.6rem;font-weight:900;letter-spacing:.08em;
  text-transform:uppercase;padding:.2rem .45rem;border-radius:.25rem}

/* ── the quiet row ─────────────────────────────────────────────────────── */
.qrow{display:flex;align-items:center;gap:.85rem;width:100%;min-height:var(--tap);
  background:var(--cream-2);border-radius:1.1rem;padding:.9rem 1rem}
.qrow:active{transform:translateY(1px)}
.qrow .qic{flex:none;width:3rem;height:3rem;border-radius:999px;overflow:hidden}
.qrow .qic img{width:100%;height:100%;object-fit:cover}
.qrow .qtx{flex:1;min-width:0}
.qrow .qtt{display:block;font-size:1.15rem;font-weight:900;text-transform:uppercase;line-height:1.1}
.qrow .qts{display:block;font-size:.9rem;color:var(--ink-2);margin-top:.1rem}
.qrow .qgo{flex:none;width:2.6rem;height:2.6rem;border-radius:999px;background:var(--cream-3);
  display:grid;place-items:center;font-size:1.1rem;font-weight:900}

/* ── the clerk peek bar ────────────────────────────────────────────────── */
.peek{display:flex;align-items:center;gap:.5rem;width:100%;background:var(--cream-2);
  border-radius:1.1rem;padding:.5rem .7rem .5rem .3rem;min-height:4.5rem}
.peek-art{flex:none;width:5rem}
.peek-art img{width:100%;display:block}
.peek-tx{flex:1;min-width:0;font-style:italic}
.peek-tx b{display:block;font-size:1.05rem;font-weight:900;font-style:italic}
.peek-tx span{display:block;font-size:.95rem;color:var(--olive);font-weight:600}
.peek-btn{flex:none;background:var(--olive);color:var(--white);border-radius:999px;
  padding:.6rem .85rem;font-size:.78rem;font-weight:900;letter-spacing:.03em;
  text-transform:uppercase;min-height:2.75rem;display:grid;place-items:center;text-align:center}

/* ── clerk illustration in a state / moment ────────────────────────────── */
.clerkart{width:100%;max-width:15rem;margin:0 auto;display:block}
.clerkart img{width:100%;display:block}
.clerkrow{display:flex;align-items:flex-end;gap:.6rem}
.clerkrow .art{flex:none;width:38%}
.clerkrow .art img{width:100%;display:block}
.clerkrow .say{flex:1;background:var(--white);border:2px solid var(--charcoal);
  border-radius:1rem;padding:.7rem .85rem;font-weight:800;font-size:1rem;margin-bottom:.8rem}

/* ── illustrated-treatment corrections ─────────────────────────────────── */
.band[hidden]{display:none}                 /* Food carries its own stamp bar */
.scene{overflow:hidden}                     /* the clerk may bleed, the page may not */
.scene-txt{width:60%}
.scene-txt .hero{font-size:clamp(2rem,9.4vw,2.7rem)}
.scene-txt .hand{font-size:.95rem;max-width:15rem}
.scene-clerk{width:56%;right:-6%;top:2.2rem}
.scene-desk{margin-top:-2.6rem}
.act-body{width:66%;padding:.9rem .8rem;gap:.7rem}
.act-tt{font-size:1.18rem}
.act-ts{font-size:.85rem}
.act-art{width:38%}
.act-ic{width:3.1rem;height:3.1rem}
.act-go{width:2.4rem;height:2.4rem}
.peek-tx b{font-size:1rem;line-height:1.15}
.peek-tx span{font-size:.9rem;line-height:1.15}
.peek-btn{font-size:.72rem;padding:.6rem .7rem;max-width:7.5rem}

/* ── the hero as ONE continuous desk ───────────────────────────────────── */
.scene{position:relative;overflow:hidden;padding-top:.2rem}
.scene-txt{position:relative;z-index:3;width:62%;padding:0 var(--gut)}
.scene-art{
  display:flex;align-items:flex-end;   /* both pieces share the desk line */
  width:100%;margin-top:-4.6rem;position:relative;z-index:1;
}
.scene-art .sa-l{width:56.7%;display:block}
.scene-art .sa-r{width:43.3%;display:block}

/* vector art fills its slot */
.scene-art{margin-top:-3.2rem}
.scene-art svg{width:100%;display:block}
.act-ic svg,.qrow .qic svg{width:100%;height:100%;display:block}
.act-art svg{width:100%;height:100%;object-fit:cover;display:block}
.peek-art svg{width:100%;display:block}
.clerkart svg{width:100%;display:block}

/* his artwork in the hero and the cards */
.scene-art{display:flex;align-items:flex-end;margin-top:-4.4rem}
.scene-art .sa-l{width:56.7%;display:block}
.scene-art .sa-r{width:43.3%;display:block}
.act-art img{width:100%;height:100%;object-fit:cover;object-position:left center;display:block}
.peek-art img{width:100%;display:block}

/* ══════════════════════════════════════════════════════════════════════════
   QUEST — built to the approved reference (09_21_06, "Good evening, Jason").
   Artwork is cut from that file at full resolution; every piece of functional
   text is real app text so it scales, translates and reaches a screen reader.
   ══════════════════════════════════════════════════════════════════════════ */
.qhead{display:flex;align-items:flex-start;gap:.7rem;padding:calc(var(--safe-t) + 1.9rem) var(--gut) .5rem}
/* the conversation bar: two buttons and air — the thread starts higher */
.qhead--slim{align-items:center;padding:calc(var(--safe-t) + .55rem) var(--gut) .3rem}
.qsp{flex:1}
.qhist{color:var(--ink)}
.qhist svg{display:block}
.qmark{flex:none;line-height:.95}
.qmark b{display:block;font-size:1.06rem;font-weight:900;letter-spacing:-.01em}
.qmark b.hot{color:var(--coral)}
.qmark .dept{display:inline-block;margin-top:.25rem;border:2px solid var(--coral);color:var(--coral);
  border-radius:.25rem;padding:.1rem .3rem;font-size:.52rem;font-weight:900;letter-spacing:.06em;
  transform:rotate(-1.5deg)}
.qgreet{flex:1;min-width:0;font-style:italic;padding-top:.1rem}
.qgreet b{display:block;font-size:1.12rem;font-weight:800;font-style:italic;line-height:1.1}
.qgreet span{display:block;font-size:.86rem;color:var(--ink-2);line-height:1.25;margin-top:.15rem}
.qav{flex:none;display:flex;align-items:center;gap:.35rem}
.qbell{position:relative;font-size:1.25rem}
.qbell i{position:absolute;top:-.3rem;right:-.4rem;background:var(--coral);color:#fff;font-style:normal;
  font-size:.6rem;font-weight:900;border-radius:999px;min-width:1.05rem;height:1.05rem;
  display:grid;place-items:center}
.qav img{width:2.5rem;height:2.5rem;border-radius:999px;display:block;border:2px solid var(--charcoal)}

/* the quest clipboard, with the clerk sitting behind it */
.qboard{position:relative;margin:.2rem var(--gut) 0;overflow:hidden;border-radius:1rem}
.qboard-art{position:absolute;right:-6%;top:0;width:56%;z-index:1}
.qboard-art img{width:100%;display:block}
.qboard-card{position:relative;z-index:2;width:64%;background:var(--cream);border:2px solid var(--ink);
  border-radius:.7rem;padding:.6rem .7rem .7rem;box-shadow:3px 3px 0 rgba(16,32,39,.18)}
.qboard-tag{display:inline-block;background:var(--olive);color:#fff;border-radius:.3rem;
  padding:.2rem .5rem;font-size:.66rem;font-weight:900;letter-spacing:.08em;text-transform:uppercase}
.qstep{display:flex;align-items:center;gap:.55rem;padding:.45rem 0;border-bottom:1px solid var(--line)}
.qstep:last-child{border-bottom:0}
.qstep .si{flex:none;width:1.7rem;height:1.7rem;border-radius:999px;display:grid;place-items:center;
  font-size:.85rem;color:#fff}
.qstep .si--coral{background:var(--coral)} .qstep .si--olive{background:var(--olive)}
.qstep .st{flex:1;min-width:0}
.qstep .st b{display:block;font-size:.86rem;font-weight:900;line-height:1.15}
.qstep .st span{display:block;font-size:.72rem;color:var(--ink-3);line-height:1.2}
.qstep .sd{flex:none;width:1.35rem;height:1.35rem;border-radius:999px;border:2px solid var(--line);
  display:grid;place-items:center;font-size:.7rem;color:#fff;font-weight:900}
.qstep .sd.on{background:var(--olive);border-color:var(--olive)}

/* the ask block */
.qask{margin:.9rem var(--gut) 0;background:var(--cream);border-radius:1rem;padding:.9rem .9rem 1rem;
  position:relative;overflow:hidden;border:1px solid var(--line)}
.qask-art{position:absolute;right:-2%;top:.4rem;width:38%}
.qask-art img{width:100%;display:block}
.qask h2{margin:0;font-size:clamp(1.35rem,6.2vw,1.75rem);line-height:1;font-weight:900;
  text-transform:uppercase;letter-spacing:-.02em;width:62%}
.qask h2 .hot{color:var(--coral)}
.qask .sub{margin:.5rem 0 .8rem;font-style:italic;font-size:.9rem;color:var(--ink-2);width:62%}
.qask form{display:flex;gap:.45rem;position:relative;z-index:2}
.qask input{flex:1;min-width:0;min-height:var(--tap);border:2px solid var(--line);border-radius:999px;
  padding:0 1rem;background:var(--white)}
.qask button{flex:none;background:var(--coral);color:#fff;border-radius:999px;padding:0 1rem;
  min-height:var(--tap);font-weight:900;font-size:.85rem;letter-spacing:.03em}

/* the four tiles, exactly as drawn */
.qtiles{display:grid;grid-template-columns:1fr 1fr;gap:.6rem;margin:.9rem var(--gut) 0}
.qtile{position:relative;border-radius:.9rem;overflow:hidden;border:1px solid var(--line);
  aspect-ratio:1/1.06;padding:0;background:var(--cream-2)}
.qtile img{width:100%;height:100%;object-fit:cover;display:block}
.qtile:active{transform:translateY(2px)}

/* coming up */
.qcoming{margin:.9rem var(--gut) 0;background:var(--cream);border:1px solid var(--line);
  border-radius:1rem;padding:.8rem .7rem}
.qcoming .lbl{font-style:italic;font-weight:900;font-size:.8rem;text-transform:uppercase;
  letter-spacing:.06em;margin-bottom:.5rem;display:block}
.qdots{display:flex;align-items:flex-start;justify-content:space-between;gap:.2rem}
.qdot{flex:1;text-align:center}
.qdot i{display:grid;place-items:center;width:2.1rem;height:2.1rem;border-radius:999px;margin:0 auto .25rem;
  font-style:normal;font-size:.95rem;color:#fff}
.qdot b{display:block;font-size:.68rem;font-weight:900;line-height:1.1}
.qdot span{display:block;font-size:.62rem;line-height:1.15;color:var(--ink-3)}
.qdot span.next{color:var(--coral);font-weight:900}
.qdot span.done{color:var(--olive);font-weight:900}

/* the tip strip */
.qtip{display:flex;align-items:center;gap:.5rem;margin:.9rem var(--gut) 0;background:var(--cream);
  border:1px solid var(--line);border-radius:1rem;padding:.5rem .8rem .5rem .3rem}
.qtip-art{flex:none;width:4.4rem}
.qtip-art img{width:100%;display:block;border-radius:.6rem}
.qtip p{margin:0;font-style:italic;font-weight:800;font-size:.92rem;line-height:1.25}

/* tiles sit squarer, like the reference */
.qtile{aspect-ratio:1/0.92}
.qboard-card{width:62%}
.qboard-art{width:52%;right:-4%}

/* the tiles keep their own proportion so nothing is clipped */
.qtile{aspect-ratio:228/246}
/* the clerk block fades into the page instead of showing a hard blurry edge */
.qboard-art{-webkit-mask:linear-gradient(to right,transparent,#000 22%),linear-gradient(to bottom,transparent,#000 14%);-webkit-mask-composite:source-in;mask:linear-gradient(to right,transparent,#000 22%),linear-gradient(to bottom,transparent,#000 14%);mask-composite:intersect}
.qbell{position:relative;font-size:1.25rem;background:none;min-height:2.75rem;min-width:2.4rem}
.qav button{background:none;padding:0;min-height:2.75rem}

/* the bell and the avatar are real buttons, so they get real tap targets */
.qbell,.qav button{min-width:2.75rem;min-height:2.75rem;display:grid;place-items:center}
.qav img{width:2.4rem;height:2.4rem}

/* ── Quest, matched to the reference ───────────────────────────────────── */
.qtiles--four{grid-template-columns:repeat(4,1fr);gap:.4rem}
.qtiles--four .qtile{aspect-ratio:228/246;border-radius:.7rem}
.qcoming-top{display:flex;align-items:center;justify-content:space-between;gap:.5rem;margin-bottom:.5rem}
.qcoming-top .lbl{margin:0}
.qview{background:var(--cream-2);border:1px solid var(--line);border-radius:999px;
  padding:.45rem .7rem;font-size:.72rem;font-weight:900;min-height:2.75rem;display:grid;place-items:center}
.qdots{position:relative}
.qdots::before{content:'';position:absolute;left:12%;right:12%;top:1rem;border-top:2px dashed var(--line);z-index:0}
.qdot{position:relative;z-index:1}
.qtip{align-items:stretch}
.qtip p{flex:1;font-size:.86rem}
.qtipcard{flex:none;width:6.6rem;background:var(--cream-2);border:1px solid var(--line);
  border-radius:.5rem;padding:.4rem .5rem;font-style:italic;font-size:.72rem;line-height:1.25;
  transform:rotate(1.2deg)}
.qtipcard b{display:block;font-style:normal;font-weight:900;font-size:.62rem;letter-spacing:.06em;
  text-transform:uppercase;color:var(--olive);margin-bottom:.15rem}
.qtipcard .hot{color:var(--coral)}

/* the clipboard is paper with a clip, not a boxed-in card */
.qboard-card{border:1px solid var(--line);box-shadow:2px 3px 0 rgba(16,32,39,.10);
  border-radius:.5rem;padding-top:1.1rem}
.qboard-card::before{content:'';position:absolute;left:50%;top:-.45rem;transform:translateX(-50%);
  width:2.6rem;height:.9rem;background:var(--charcoal);border-radius:.25rem}

/* ══════════════════════════════════════════════════════════════════════════
   LAYERED, NOT CUT
   The picture goes down first, edge to edge. The UI sits on top of it. Nothing
   is chopped out of an illustration to make it fit a box.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── Quest: the clerk is the backdrop, the card sits on him ────────────── */
.qstage{position:relative;margin:.3rem 0 0;min-height:15rem}
.qstage-bg{position:absolute;inset:0;display:block;overflow:hidden}
.qstage-bg img{width:100%;height:100%;object-fit:cover;object-position:70% 40%;display:block}
.qstage-bg::after{                       /* the picture melts into the page   */
  content:'';position:absolute;inset:0;
  background:linear-gradient(to right,var(--cream) 4%,rgba(255,244,222,.55) 42%,rgba(255,244,222,0) 68%),
             linear-gradient(to bottom,var(--cream) 0,rgba(255,244,222,0) 18%,rgba(255,244,222,0) 76%,var(--cream) 100%);
}
.qstage-card{
  position:relative;z-index:2;width:66%;margin:1.1rem 0 1.1rem var(--gut);
  background:rgba(255,248,232,.94);border:1px solid var(--line);border-radius:.6rem;
  padding:1.1rem .8rem .7rem;box-shadow:2px 3px 0 rgba(16,32,39,.12);backdrop-filter:blur(2px);
}
.qstage-card::before{content:'';position:absolute;left:50%;top:-.45rem;transform:translateX(-50%);
  width:2.6rem;height:.9rem;background:var(--charcoal);border-radius:.25rem}

/* ── the menu button replaces the avatar ───────────────────────────────── */
.qmenu{display:grid;gap:.22rem;align-content:center;justify-items:center;
  min-width:2.75rem;min-height:2.75rem;background:none}
.qmenu span{display:block;width:1.35rem;height:.16rem;background:var(--ink);border-radius:2px}

/* ── action cards: picture underneath, words on top ────────────────────── */
.act{position:relative;overflow:hidden}
.act-bg{position:absolute;inset:0;z-index:0;display:block}
.act-bg img{width:100%;height:100%;object-fit:cover;object-position:right center;display:block}
.act-bg::after{content:'';position:absolute;inset:0;
  background:linear-gradient(to right,currentColor 0,currentColor 46%,rgba(0,0,0,0) 82%)}
.act--olive .act-bg::after{background:linear-gradient(to right,#83952F 0,#83952F 46%,rgba(131,149,47,0) 84%)}
.act--coral .act-bg::after{background:linear-gradient(to right,#FF4B28 0,#FF4B28 46%,rgba(255,75,40,0) 84%)}
.act--amber .act-bg::after{background:linear-gradient(to right,#FFC233 0,#FFC233 46%,rgba(255,194,51,0) 84%)}
.act-body{position:relative;z-index:2;width:70%}
.act-art{display:none}                   /* superseded by the layered backdrop */

/* ── tiles: art underneath, a real word on top ─────────────────────────── */
.qtile{position:relative;overflow:hidden;display:block;padding:0}
.qtile-bg{position:absolute;inset:0;display:block}
.qtile-bg img{width:100%;height:100%;object-fit:cover;object-position:center 62%;display:block}
.qtile-bg::after{content:'';position:absolute;inset:0;
  background:linear-gradient(to bottom,rgba(16,32,39,.42) 0,rgba(16,32,39,0) 48%)}
.qtile-lb{position:relative;z-index:2;display:block;padding:.5rem .5rem 0;
  font-size:.8rem;font-weight:900;line-height:1.05;text-transform:uppercase;
  color:#fff;text-shadow:0 1px 3px rgba(0,0,0,.45)}

/* ── the tab bar, sitting like the drawn one ───────────────────────────── */
.tabbar{border-radius:1.2rem 1.2rem 0 0;box-shadow:0 -3px 0 rgba(16,32,39,.12)}
.tab svg{fill:none;stroke:currentColor;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
.tab span{font-size:.66rem;letter-spacing:.1em}
.tab[aria-current="page"]::after{content:'';position:absolute;bottom:.55rem;width:1.1rem;height:.16rem;
  background:var(--coral);border-radius:2px}
.tab{position:relative}

/* the whole scene, not a zoom into it */
.qstage{min-height:17.5rem}
.qstage-bg img{object-position:62% 30%;transform:scale(1.02)}

/* the artwork carries its own painted words — push them out of frame so the
   real, readable label on top is the only wording */
.qtile-bg img{object-position:center 88%}
.qtile{aspect-ratio:228/230}
.qtile-lb{padding:.45rem .45rem 0;font-size:.74rem}

/* ══ the clerk stays visible: picture in full, card tucked over the desk ══ */
.qstage--under{min-height:0;margin:.3rem 0 0}
.qstage--under .qstage-bg{position:relative;inset:auto;display:block}
.qstage--under .qstage-bg img{width:100%;height:auto;object-fit:contain;object-position:center;transform:none}
.qstage--under .qstage-bg::after{
  background:linear-gradient(to bottom,rgba(255,244,222,0) 55%,var(--cream) 96%);
}
.qstage--under .qstage-card{
  width:auto;margin:-3.4rem var(--gut) 0;position:relative;z-index:2;
}

/* the quest steps are buttons now */
.qstep{width:100%;background:none;text-align:left}
.qstep:active{background:var(--cream-2)}
.qstep .sd{color:var(--ink-3);font-weight:900}
.qstep .sd.on{color:#fff}

/* the nearby map */
.nearmap{width:100%;height:15rem;border-radius:1rem;border:2px solid var(--charcoal);overflow:hidden;margin-top:.5rem;background:var(--cream-2)}
.vbadges{display:block;margin-top:.25rem}
.vbadge{display:inline-block;font-size:.62rem;font-weight:900;letter-spacing:.05em;text-transform:uppercase;padding:.18rem .45rem;border-radius:.3rem;background:var(--cream-2);color:var(--ink-3)}
.vbadge--open{background:#E4EFD3;color:#4E5510}
.vbadge--shut{background:#F6DDD8;color:#A92D26}
/* the shop's own facts — the detail screen used to drop all of these */
.vfacts{display:flex;align-items:center;flex-wrap:wrap;gap:.45rem;margin:.35rem 0 0}
.vfacts span{color:var(--ink-2);font-size:.92rem}
.vhours{margin:.3rem 0 0;color:var(--ink-3);font-size:.85rem}
.vcaveat{margin:.5rem 0 0;color:var(--ink-2);font-size:.9rem;font-style:italic;
  border-left:3px solid var(--mustard);padding-left:.6rem}
.advice{margin:.6rem 0 0;padding-left:1.1rem}
.advice li{margin:.4rem 0;color:var(--ink-2);line-height:1.4}

/* ══ QUEST · JOURNEY · ME (Percy-first) ═══════════════════════════════════ */

/* Percy front and centre, speech first */
.percy{display:flex;align-items:flex-end;gap:.4rem;padding:.4rem var(--gut) 0}
.percy-art{flex:0 0 38%;max-width:10.5rem}
.percy-art svg{width:100%;height:auto;display:block}
/* the drawn Percy ships on his own cream ground — frame it on purpose, like
   a staff portrait on the department wall */
.percy-art img{width:100%;height:auto;display:block;border:2px solid var(--charcoal);
  border-radius:1rem;box-shadow:.22rem .22rem 0 var(--charcoal)}
.percy-says{flex:1;background:var(--white);border:2px solid var(--charcoal);
  border-radius:1.1rem;border-bottom-left-radius:.2rem;padding:.85rem 1rem;
  margin-bottom:1.6rem;position:relative}
.percy-says p{margin:0;font-size:1.08rem;line-height:1.35;font-weight:700;color:var(--ink)}
.percy-says::after{content:"";position:absolute;left:-.65rem;bottom:.75rem;
  width:.9rem;height:.9rem;background:var(--white);
  border-left:2px solid var(--charcoal);border-bottom:2px solid var(--charcoal);
  transform:rotate(45deg)}

/* ── PERCY'S THREAD ───────────────────────────────────────────────────────
   The conversation, continuing under his greeting. Percy keeps the left with
   his portrait; you answer from the right, no portrait — the shape alone says
   who is talking, so neither side needs a name label. */
/* LOCKED, not endless: the box scrolls, the page does not grow forever.
   overscroll-contain stops a flick at the end of the chat from dragging the
   whole screen with it. */
.thread{display:flex;flex-direction:column;gap:.75rem;padding:.9rem var(--gut) 0;
  max-height:58vh;overflow-y:auto;overflow-x:hidden;overscroll-behavior:contain;
  -webkit-overflow-scrolling:touch;scrollbar-width:thin}
.thread:empty{display:none}
.thread--v{max-height:42vh;padding-left:0;padding-right:0}
/* the way back into what he said before */
.earlier{align-self:center;flex:none;font-size:.82rem;font-weight:900;letter-spacing:.04em;
  text-transform:uppercase;color:var(--ink-2);background:var(--cream-2);
  border:2px dashed var(--line);border-radius:999px;padding:.45rem .9rem;margin-bottom:.2rem}
.daydiv{display:flex;align-items:center;gap:.6rem;margin:.2rem 0}
.daydiv::before,.daydiv::after{content:"";flex:1;height:2px;background:var(--line)}
.daydiv span{font-size:.72rem;font-weight:900;letter-spacing:.1em;text-transform:uppercase;
  color:var(--ink-3)}
.turn{display:flex;gap:.45rem;align-items:flex-end;
  animation:turnin .32s cubic-bezier(.2,.9,.3,1.15) both}
/* room for the bubble's own tail INSIDE the box. Without this the tail hangs
   past the right edge, the thread becomes horizontally scrollable, and the
   whole chat slides left and right under your thumb. */
.turn--you{justify-content:flex-end;padding-right:.7rem}
/* Percy stacks: his face + words on one line, then any document full width */
.turn--percy{flex-direction:column;align-items:stretch;gap:.55rem}
.turn-head{display:flex;gap:.45rem;align-items:flex-end}
/* The avatar reserves its box before the image loads: the <img> now carries
   intrinsic width/height (app.js), and this min-height is the floor for the
   shortest of them so the row never collapses mid-load. A single
   aspect-ratio here would be wrong — percy.jpg is square, the variants are
   3:4 — which is why the sizing lives on the element, not in this rule. */
.turn-art{flex:0 0 3.4rem;align-self:flex-end;min-height:3.4rem}
.turn-art img{width:100%;height:auto;display:block;border:2px solid var(--charcoal);
  border-radius:.8rem;box-shadow:.16rem .16rem 0 var(--charcoal)}
.turn-head .bub{flex:1;min-width:0}
.bub{border:2px solid var(--charcoal);border-radius:1.1rem;padding:.8rem .95rem;
  position:relative}
/* pre-line keeps the USER's typed line breaks; Percy's lines are built as
   spans by percyText() with real hanging indents */
.bub p{margin:0;font-size:1.02rem;line-height:1.4;font-weight:700;color:var(--ink);
  white-space:pre-line}
.bub p .ln,.bub p .bl{display:block;white-space:normal}
/* the hanging indent: wrapped bullet text aligns with the first WORD */
.bub p .bl{position:relative;padding-left:1.15em}
.bub p .bl>i{position:absolute;left:0;top:0;font-style:normal}
.bub p .bl--n{padding-left:1.5em}
.bub p .lgap{display:block;height:.5em}
.bub--percy{background:var(--white);border-bottom-left-radius:.2rem}
.bub--percy::after{content:"";position:absolute;left:-.62rem;bottom:.7rem;
  width:.85rem;height:.85rem;background:var(--white);
  border-left:2px solid var(--charcoal);border-bottom:2px solid var(--charcoal);
  transform:rotate(45deg)}
.bub--you{background:var(--charcoal);border-bottom-right-radius:.2rem;max-width:78%}
.bub--you p{color:var(--cream)}
.bub--you::after{content:"";position:absolute;right:-.62rem;bottom:.7rem;
  width:.85rem;height:.85rem;background:var(--charcoal);
  border-right:2px solid var(--charcoal);border-bottom:2px solid var(--charcoal);
  transform:rotate(-45deg)}
.bub-note{margin:0;font-size:.8rem;line-height:1.35;color:var(--ink-3)}
.turn-acts{display:flex;flex-wrap:wrap;gap:.4rem}
.chip--go{background:var(--coral);color:var(--white);border-color:var(--charcoal)}
/* he is thinking, and the dots say so for exactly as long as he is */
.dots{display:flex;gap:.3rem;align-items:center;height:1.1rem}
.dots i{width:.5rem;height:.5rem;border-radius:50%;background:var(--ink-3);
  animation:dotb 1.1s ease-in-out infinite}
.dots i:nth-child(2){animation-delay:.16s}
.dots i:nth-child(3){animation-delay:.32s}
@keyframes turnin{from{opacity:0;transform:translateY(9px)}to{opacity:1;transform:none}}
@keyframes dotb{0%,60%,100%{transform:translateY(0);opacity:.45}
                30%{transform:translateY(-.3rem);opacity:1}}
@media (prefers-reduced-motion:reduce){
  /* the dots must keep moving or "thinking" looks like "stuck" — they fade
     rather than hop, so nothing translates */
  .dots i{animation:dotf 1.4s ease-in-out infinite !important}
}
@keyframes dotf{0%,60%,100%{opacity:.3}30%{opacity:1}}

/* the greeting block inside a room already sits in a .pad — it must not add
   the gutter a second time, or it steps in from everything around it */
.percy--room{padding-left:0;padding-right:0}

/* WHERE ARE YOU — quiet, one line + three chips. Answering changes the door
   Percy opens, so it sits right under his greeting. */
.placeask{padding-top:.7rem;padding-bottom:0;display:flex;flex-direction:column;gap:.5rem}
.place-q{font-size:.82rem;font-weight:900;letter-spacing:.08em;text-transform:uppercase;
  color:var(--ink-3)}
.place-pill{align-self:flex-start;font-size:.8rem;font-weight:800;color:var(--ink-2);
  background:var(--cream-2);border:2px solid var(--line);border-radius:999px;
  padding:.35rem .8rem;min-height:2.2rem}

/* an allergy clash on a dish the user LOOKED UP — warning, not concealment */
.dc-allergy{margin:.55rem 0 0;font-weight:800;color:var(--red);
  border:2px solid var(--red);border-radius:.6rem;padding:.5rem .7rem;
  background:#FBEDEA}

/* ONE main action */
.qmain{display:block;width:100%;background:var(--white);border:2px solid var(--charcoal);
  border-radius:1.1rem;padding:1.05rem 1.05rem 1.1rem;box-shadow:.28rem .28rem 0 var(--charcoal)}
.qmain h2{margin:0;font-size:1.35rem;font-weight:900;line-height:1.15;color:var(--ink)}
.qmain p{margin:.45rem 0 .85rem;font-size:.95rem;color:var(--ink-2);line-height:1.4}
.qmain .btn{margin:0}
.qmain--wide{border-radius:1.1rem;cursor:pointer}
.qmain--wide .btn{display:inline-flex;width:auto;margin-top:.7rem;padding:.6rem 1rem;min-height:0}

/* Ask Percy, slim variant: just the input */
.qask--slim{padding:.8rem .9rem}
/* inside a .pad the gutter is already applied — a second one steps the box in
   from everything above it, which reads as the chat shifting sideways */
.qask--flush{margin-left:0;margin-right:0}
.qask--slim form{margin:0}

/* Something else — folded away until wanted */
.qelse{margin-top:1rem}
.qelse summary{display:inline-block;cursor:pointer;font-weight:800;color:var(--ink-2);
  padding:.55rem .95rem;border:2px dashed var(--line);border-radius:999px;
  list-style:none;-webkit-user-select:none;user-select:none}
.qelse summary::-webkit-details-marker{display:none}
.qelse[open] summary{border-style:solid;background:var(--cream-2)}

/* ── JOURNEY — the winding map ──────────────────────────────────────────── */
.jsum{margin:.1rem var(--gut) 0;font-size:var(--t-sub);font-weight:800;color:var(--ink-3)}

/* the journey tap sheet */
#jsheet{position:fixed;inset:0;z-index:60;background:rgba(16,32,39,.38);
  display:flex;align-items:flex-end}
.jsheet-card{width:100%;background:var(--cream);border-radius:1.2rem 1.2rem 0 0;
  border-top:2.5px solid var(--charcoal);padding:1.2rem var(--gut)
  calc(1.2rem + var(--safe-b));display:flex;flex-direction:column;gap:.7rem}
.jsheet-card h3{margin:0;font-size:1.2rem;font-weight:900;text-transform:uppercase}
.jsheet-sub{margin:0;color:var(--ink-2)}
.jsheet-card ul{margin:0;padding-left:1.2rem;color:var(--ink-2)}
.jsheet-card li{margin:.2rem 0}

/* ── the daily-history + moment sheets ────────────────────────────────── */
/* #aisheet was MISSING from this list (09-06): the consent sheet rendered as
   an unstyled div below the app — invisible — so an un-consented ask showed
   typing dots forever. The sheet must always be a real overlay.
   AND IT HAPPENED TWICE MORE. #ansheet (analytics) and #memsheet (memory sync)
   were both missing on 2026-09-11 — same class, same cause: a sheet is added in
   app.js and this selector is not updated, so it renders as a plain div with no
   stacking context and the tab bar (z-index 30) paints over its bottom. For
   #ansheet that buried "Stop counting on this phone" — the opt-out — under the
   bar on any render tall enough to push it down: red on Linux CI every push
   since 8a745eb while macOS stayed green, and true on any phone with a larger
   text size. THE LIST IS THE BUG. Every body-level sheet in app.js belongs
   here; grep `wrap.id = '` in proto/app.js and this selector must name all of
   them (memsheet, aisheet, ansheet, subsheet, hsheet, dsheet, msheet). */
#hsheet,#msheet,#dsheet,#subsheet,#aisheet,#ansheet,#memsheet{position:fixed;inset:0;z-index:65;background:rgba(16,32,39,.38);
  display:flex;align-items:flex-end}
.hsheet-card{width:100%;max-height:82vh;background:var(--cream);
  border-radius:1.2rem 1.2rem 0 0;border-top:2.5px solid var(--charcoal);
  padding:1rem var(--gut) calc(1rem + var(--safe-b));
  display:flex;flex-direction:column;gap:.7rem}
.hsheet-top{display:flex;align-items:center;gap:.6rem}
.hsheet-top h3{margin:0;flex:1;font-size:1.2rem;font-weight:900;text-transform:uppercase}
.hback{background:none;padding:.2rem 0;font-weight:900;color:var(--ink)}
.hclose{background:none;min-width:2.4rem;min-height:2.4rem;font-size:1.05rem;
  font-weight:900;color:var(--ink)}
.hsheet-scroll{overflow-y:auto;-webkit-overflow-scrolling:touch;min-height:0;
  display:flex;flex-direction:column;gap:.5rem}
.hday{display:flex;align-items:baseline;gap:.6rem;text-align:left;
  background:var(--cream-2);border:2px solid var(--line);border-radius:.9rem;
  padding:.7rem .85rem}
.hday b{font-weight:900}
.hday span{margin-left:auto;font-size:.8rem;color:var(--ink-2);flex:none}
/* past pages read back, never act: no button inside an old turn does anything */
#hsheet .thread button,#hsheet .thread [data-vgo]{pointer-events:none;opacity:.55}

/* ── JOURNEY, the diary (09-02) ───────────────────────────────────────── */
.jour{padding:.3rem var(--gut) 5.5rem;display:flex;flex-direction:column;gap:.85rem}
.jdate{margin:0;font-size:.76rem;font-weight:900;letter-spacing:.14em;color:var(--ink-2)}
.jask{margin:0;font-size:1.55rem;font-weight:900;line-height:1.05}
.jmood{display:flex;gap:.45rem;flex-wrap:wrap}
.jmood-c[aria-pressed="true"]{background:var(--charcoal);color:var(--cream);border-color:var(--charcoal)}
.jlog{font-size:1.02rem}
.jnotice{display:flex;gap:.65rem;align-items:flex-start;background:var(--cream-2);
  border:2.5px solid var(--charcoal);border-radius:1rem;padding:.8rem .85rem}
.jnotice b{font-size:.78rem;font-weight:900;letter-spacing:.1em;text-transform:uppercase}
.jnotice p{margin:.2rem 0 0;line-height:1.35}
.jday{border:2px solid var(--line);border-radius:1rem;padding:.75rem .85rem;background:var(--cream)}
.jday header{display:flex;gap:.6rem;align-items:baseline}
.jday header b{font-weight:900;letter-spacing:.08em;font-size:.82rem}
.jday-mood{font-size:.88rem}
.jday-w{margin-left:auto;font-weight:900;font-size:.88rem;flex:none}
.jrow{margin:.4rem 0 0;font-size:.95rem;line-height:1.35}
.jrow--fact{color:var(--ink-2);font-size:.84rem}
.jpercy{margin:.55rem 0 0;font-style:italic;color:var(--ink-2);
  border-top:2px solid var(--line);padding-top:.5rem}
.jempty{margin:.4rem 0 0;color:var(--ink-2)}
.msheet-body{gap:.55rem}
.msheet-body label{font-weight:900;font-size:.9rem;margin-top:.25rem}
.msheet-body input[type=text],.msheet-body input[type=number]{
  border:2px solid var(--charcoal);border-radius:.7rem;padding:.6rem .7rem;
  font:inherit;background:var(--cream);min-width:0}
.mnum{display:flex;align-items:center;gap:.9rem;flex-wrap:wrap}
.mnum-g{display:flex;align-items:center;gap:.45rem;flex:none}
.mnum label{margin-top:0}
.mnum input{width:5.4rem}
.mnum span{color:var(--ink-2);font-size:.88rem}
.msheet-foot{margin:.15rem 0 0;font-size:.8rem;color:var(--ink-2)}

/* ── the free-week clock on Quest (soft lock, 09-03) ──────────────────── */
/* The subscribe sheet is the one MOMENT sheet, not a drawer: it sits centred
   (Jason 09-04), a card in the middle of the screen rather than sliding up. */
#subsheet{align-items:center;justify-content:center;padding:0 var(--gut)}
#subsheet .hsheet-card{width:100%;max-width:24rem;border-radius:1.2rem;
  border:2.5px solid var(--charcoal)}

.trialbar{display:block;width:auto;margin:0 var(--gut) .45rem;padding:.45rem .9rem;
  border-radius:.85rem;background:var(--cream-2);border:2px solid var(--line);
  font-weight:900;font-size:.85rem;text-align:center;color:var(--ink)}
button.trialbar{cursor:pointer;font:inherit;font-weight:900;font-size:.85rem}
.trialbar--over{background:var(--coral);border-color:var(--coral);color:#fff}

/* ── the living day strip on Quest (09-02) ────────────────────────────── */
.dayplan{padding:.15rem var(--gut) .4rem;display:flex;flex-direction:column;gap:.45rem}
/* FIRST LIGHT (Cycle 5) — VISIBILITY ONLY. Nothing here restyles the board
   or the trial bar: on a first run the loudest object on the screen simply
   has not arrived yet, and at Moment 3 it slides in once, above the thread.
   The global prefers-reduced-motion rule (top of this file) already turns the
   animation off for anyone who asked for that. */
body.first-light .dayplan,
body.first-light .trialbar{display:none}
body.first-light.fl-board .dayplan{display:flex;animation:fl-in 200ms ease-out}
@keyframes fl-in{from{opacity:0;transform:translateY(-6px)}to{opacity:1;transform:none}}
.dnext{border:2.5px solid var(--charcoal);border-radius:1rem;background:var(--cream-2);
  padding:.6rem .8rem;display:flex;flex-direction:column;gap:.45rem}
.dnext-t{font-size:.7rem;font-weight:900;letter-spacing:.14em;color:var(--ink-2)}
.dnext b{font-size:1.05rem;font-weight:900}
.dnext-acts,.dswap{display:flex;gap:.4rem;flex-wrap:wrap}
/* ── THE NOW CARD FOLDS (Cycle 7c, 2026-09-09) ─────────────────────────────
   Jason: "can we design it in a way that the pills can pull up and drop down?"
   Collapsed, the card is one row that still carries the single next action —
   the member never expands to act. The timeline never folds (it is the only
   door to the whole-day sheet); the kcal line does, because it is a number to
   read rather than something to do. No new colours and no new components:
   the existing .chip, the existing .dnext, one chevron.
   Reduced motion needs no media query here — app.css L61 already kills every
   transition globally. */
.dnext-h{position:absolute;top:0;right:0;display:flex;align-items:center;justify-content:flex-end;
  gap:.3rem;min-height:2.75rem;width:100%;padding:0 .8rem;background:none;border:0;
  cursor:pointer;touch-action:none}
.dnext{position:relative}
.dnext-cv{font-size:1.1rem;font-weight:900;line-height:1;color:var(--ink-2);
  transition:transform 200ms cubic-bezier(.2,.8,.2,1)}
.dayplan[data-now="shut"] .dnext-cv{transform:rotate(180deg)}
.dnext-fold{overflow:hidden;max-height:22rem;opacity:1;visibility:visible;
  transition:max-height 200ms cubic-bezier(.2,.8,.2,1),opacity 160ms linear,
    visibility 0s linear 0s}
/* visibility flips at the END of the fold, so the panel is genuinely hidden
   from hit-testing and from assistive tech once it is closed — max-height
   alone leaves the chips clickable and readable at zero height */
.dayplan[data-now="shut"] .dnext-fold{max-height:0;opacity:0;visibility:hidden;
  transition:max-height 200ms cubic-bezier(.2,.8,.2,1),opacity 160ms linear,
    visibility 0s linear 200ms}
/* SHUT IS ONE ROW (spec §3): handle, time, title, one action. 56px, not a
   stack — the whole point is the screen the card gives back. */
.dayplan[data-now="shut"] .dnext{flex-direction:row;align-items:center;gap:.5rem;
  padding:.35rem .8rem}
.dayplan[data-now="shut"] .dnext-t{flex:none}
/* the chip already sits between the title and the chevron when shut, so the
   title needs no clearance — and it needs a floor, or "🍜 Lunch" truncates to
   "🍜 .." beside a wide primary chip on a 390px screen (caught in the visual
   baseline, not by a test) */
.dayplan[data-now="shut"] .dnext>b{flex:1 1 auto;min-width:5rem;overflow:hidden;
  white-space:nowrap;text-overflow:ellipsis;padding-right:0}
.dayplan[data-now="shut"] .dnext-p .chip{flex:0 1 auto;min-width:0;overflow:hidden;
  white-space:nowrap;text-overflow:ellipsis}
/* the action sits ABOVE the full-width handle, or the handle eats its tap */
.dayplan[data-now="shut"] .dnext-p{position:relative;z-index:1;flex:none}
/* the one action that survives the fold */
.dnext-p{display:none}
.dayplan[data-now="shut"] .dnext-p{display:flex;gap:.4rem;flex-wrap:wrap}
.dayplan[data-now="shut"] .dkcal{display:none}
/* the title sits beside the handle, so it must not run under the chevron */
.dnext>b{padding-right:2rem}
.dnext--closed{align-items:flex-start}
.dtl{display:flex;gap:.75rem;overflow-x:auto;background:none;padding:.1rem 0;
  scrollbar-width:none;text-align:left}
.dtl::-webkit-scrollbar{display:none}
.dtl-i{flex:none;font-size:.78rem;font-weight:700;color:var(--ink-2);white-space:nowrap}
.dtl-i.is-done{opacity:.55}
.dtl-i.is-next{color:var(--ink);font-weight:900}
.dnext--quiet{border-style:dashed;background:none}
/* the screen is an app, not a page: no pinch zoom (Jason 09-02). The meta
   tag asks; this enforces it where user-scalable is ignored (iOS Safari). */
html,body{touch-action:pan-x pan-y}
.drow{display:flex;align-items:center;gap:.5rem}
.drow-m{flex:none;width:1rem;font-weight:900}
.drow-t{flex:none;font-size:.8rem;color:var(--ink-2);width:4.6rem}
.drow b{flex:1;font-size:.95rem;font-weight:700}

/* ── the tab bar's entrance — Jason's call 2026-08-27 ─────────────────────
   iOS floats fixed-bottom bars for a beat while a standalone app settles its
   viewport. Rather than fight the OS, the bar OWNS it: hovers, drops as the
   splash fades, bounces twice, settles. Timed to land right after the splash
   (900ms) so it also masks the settle window. reduced-motion kills it via
   the global rule. */
.tabbar{animation:tabdrop .85s cubic-bezier(.33,.68,.4,1) .9s both}
@keyframes tabdrop{
  0%{transform:translateY(-2.6rem)}
  50%{transform:translateY(0)}
  66%{transform:translateY(-.6rem)}
  80%{transform:translateY(0)}
  90%{transform:translateY(-.2rem)}
  100%{transform:translateY(0)}
}

/* ══ ONE PERCY CONVERSATION SHELL ═════════════════════════════════════════
   Quest, Chef, Trainer and Nearby are the same room with different hats:
   header → ONE scrolling conversation → quick replies → fixed composer.
   The old layout nested a scrolling thread inside a scrolling page; on iOS a
   swipe starting on a bubble was claimed by the inner box and, whenever the
   box had nothing to scroll, moved NOTHING. One scroller retires that bug
   structurally instead of patching around it. */
body.chat-mode{overflow:hidden;height:100dvh}
body.chat-mode .app{min-height:0;height:100%;padding-bottom:0}
.screen--chat{position:fixed;left:0;right:0;top:0;height:var(--vvh,100dvh);
  /* pinned to the VISUAL viewport while the keyboard is up: height above is
     visualViewport.height, and this offset follows any shove iOS gives the
     page — so the composer at the flex-bottom is always right on the
     keyboard's top edge */
  transform:translateY(var(--vv-top,0px));
  display:flex;flex-direction:column;background:var(--cream);z-index:20}
/* keyboard closed: leave room for the tab bar. Open: the keyboard owns that
   edge (app.js sets --vvh from visualViewport and body.kb-open). */
body:not(.kb-open) .screen--chat{padding-bottom:calc(var(--tabbar) + var(--safe-b))}
body.kb-open .tabbar{display:none}
/* CSS-only belt for the same rule: typing in a composer means the keyboard
   owns the bottom edge — no JS timing can un-hide the bar mid-focus */
body:has(.composer input:focus) .tabbar{display:none}
body:has(.composer input:focus) .screen--chat{padding-bottom:0}
.screen--chat .chat-head{flex:none}
.chat-scroll{flex:1;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch;
  overscroll-behavior:contain;padding-bottom:.6rem;
  display:flex;flex-direction:column}
/* a short conversation hugs the composer, like every messaging app */
.chat-scroll > .thread{margin-top:auto}
/* …EXCEPT at first light, before the board lands (Mira 2026-09-08). With one
   turn in the thread, hugging the composer left ~430px of empty cream above
   Percy's greeting on a 390px-wide phone — half the viewport, and it reads as
   "the conversation scrolled away", not as calm. Top-anchored, the greeting
   sits under the header with room beneath it, the way a new thread opens in
   any messaging app. Position only; the moment fl-board lands at Moment 3
   this stops applying and the thread hugs the composer again, as today. */
body.first-light:not(.fl-board) .chat-scroll > .thread{margin-top:0}
/* inside the shell the thread is content, not its own scroll box */
.screen--chat .thread{max-height:none;overflow:visible}
.quick{flex:none;display:flex;gap:.45rem;overflow-x:auto;padding:.5rem var(--gut) .15rem;
  scrollbar-width:none;-webkit-overflow-scrolling:touch}
.quick::-webkit-scrollbar{display:none}
.quick .chip{flex:none;white-space:nowrap}
.quick:empty{display:none}
.composer{flex:none;display:flex;gap:.45rem;align-items:center;
  padding:.55rem var(--gut) .6rem;background:var(--cream);border-top:1px solid var(--line)}
/* 16px floor: a smaller input makes iOS zoom the page on focus */
.composer input{flex:1;min-width:0;min-height:var(--tap);border:2px solid var(--line);
  border-radius:999px;padding:0 1rem;background:var(--white);font-size:1rem}
.composer .send{flex:none;width:var(--tap);min-height:var(--tap);border-radius:999px;
  background:var(--coral);color:#fff;font-weight:900;font-size:1.2rem;
  display:grid;place-items:center;text-align:center;padding:0}
.composer .send:disabled{background:var(--cream-2);color:var(--ink-3)}
/* small print that used to be a page footer now sits inside the scroll */
.chat-scroll .foot{margin:.6rem var(--gut) .2rem}
/* a decision/venue document inside the stream spans the room's width */
.turn .dc{margin:0}
/* venue card in the conversation */
.vcard{border:2px solid var(--charcoal);border-radius:1rem;background:var(--white);
  padding:.85rem .95rem;display:flex;flex-direction:column;gap:.3rem}
.vcard .vname{margin:0;font-size:1.15rem;font-weight:900;line-height:1.15;text-transform:none}
/* Google place photo on the venue card (proxied) — banner crop, never a wall */
.vcard .vphoto{width:100%;height:8.5rem;object-fit:cover;border-radius:.65rem;
  border:1px solid var(--line);margin-bottom:.45rem;background:var(--cream-2)}
.vcard .vmeta{color:var(--ink-2);font-size:.9rem}
.vcard .vacts{display:flex;flex-wrap:wrap;gap:.4rem;margin-top:.45rem}
/* the map, when asked for, rides inside a turn */
.turn .nearmap{margin-top:0}
/* the place pill rides quietly at the top of the conversation */
.chat-scroll .place-pill{margin:.6rem var(--gut) 0}
/* chips that are links (Maps ↗) look identical to chip buttons */
a.chip{text-decoration:none;display:inline-flex;align-items:center}
/* the all-places list, as rows inside one card */
.vcard--list{padding:.3rem .4rem}
.vrow{display:block;width:100%;padding:.6rem .55rem;border-bottom:1px solid var(--line)}
.vrow:last-child{border-bottom:0}
.vrow b{display:block;font-size:1rem;line-height:1.2}
.vrow span{display:block;font-size:.82rem;color:var(--ink-3)}
.vrow:active{background:var(--cream-2)}
/* ── kcal counting (2026-09-05) ─────────────────────────────────────────── */
/* the day's counted-so-far line, under the day strip */
.dkcal{font-size:.78rem;font-weight:800;color:var(--ink-2);background:var(--cream-2);
  border:1px solid var(--line);border-radius:999px;padding:.18rem .65rem;align-self:flex-start}
/* one scanned ingredient: name/portion · ~kcal · ½ ✕ */
.scanrow{display:flex;align-items:center;gap:.5rem;padding:.45rem 0;border-bottom:1px solid var(--line)}
.scanrow-tx{flex:1;display:flex;flex-direction:column;min-width:0}
.scanrow-tx b{font-size:.95rem}
.scanrow-p{font-size:.78rem;color:var(--ink-3)}
.scanrow-n{font-weight:900;white-space:nowrap}
.scanrow-acts{display:flex;gap:.3rem}
.scanrow-acts .chip{min-height:2rem;padding:.1rem .55rem}
.scantotal{display:flex;flex-direction:column;gap:.15rem;padding-top:.6rem}
.scantotal span{font-size:.85rem;color:var(--ink-2)}
.scanleft{font-weight:800}
/* the composer camera — Percy counts what you snap (09-05) */
.composer .camb{flex:none;width:var(--tap);min-height:var(--tap);border-radius:999px;
  border:2px solid var(--charcoal);background:var(--white);font-size:1.25rem;
  display:flex;align-items:center;justify-content:center;padding:0}
.composer .camb:active{background:var(--cream-2)}
/* recipe/session section headings inside Percy's bubble (09-05: "fonts
   arranged so it's easier to read") */
.bub p .sec-ln{display:block;margin:.55em 0 .15em;font-size:.78rem;font-weight:900;
  letter-spacing:.08em;text-transform:uppercase;color:var(--ink-2)}
/* the weekly review card at the top of Journey (09-06) */
.jweek{border-width:2px;border-color:var(--charcoal)}
.jweek header b{letter-spacing:.06em}
