/* ============================================================= *
 *  PlanOS — Switch home-menu vibe. Usefulness first; the
 *  animation is spring + glow on transform/opacity only (60fps),
 *  and fully disabled under prefers-reduced-motion.
 * ============================================================= */
:root{
  /* PlanOS brand kit v4 — object-only quest/map: blue=route, cyan=checkpoint, green=done, red=landmark/flag. NO yellow (not a core color), no faces, no rainbow. */
  --bg:#061226; --surface:#101F3A; --surface2:#17294A; --line:#24395F; --line2:#365389;
  --txt:#F6F8FF; --muted:#A8B6D1; --faint:#6E7C97;
  --accent:#2D7CFF; --accent2:#63D4FF; --accent-ink:#ffffff;
  --accent-soft:rgba(45,124,255,.18); --cyan-soft:rgba(99,212,255,.16);
  --done:#42C978; --prog:#3b9dff; --block:#FF5A52; --review:#63D4FF; --todo:#8b97ad; --backlog:#6b7790; --cancel:#6b7790;
  --warn:#FF5A52; --warn-soft:rgba(255,90,82,.15);
  --r:20px; --r-sm:13px; --r-xs:9px;
  --sh:0 2px 6px rgba(0,0,0,.30),0 12px 34px rgba(0,0,0,.34);
  --sh-lg:0 24px 70px rgba(0,0,0,.55);
  --ring:0 0 0 3px var(--bg),0 0 0 6px var(--accent2);
  --spring:cubic-bezier(.2,.85,.25,1.15);
  --ease:cubic-bezier(.3,.7,.3,1);
  --ff:ui-rounded,"SF Pro Rounded","SF Pro Display",-apple-system,BlinkMacSystemFont,Inter,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
}
[data-theme="light"]{
  --bg:#e9ecf2; --surface:#ffffff; --surface2:#f1f3f8; --line:#dde1ea; --line2:#c7cdda;
  --txt:#1a1d24; --muted:#5b6678; --faint:#8a93a6;
  --accent-soft:rgba(45,124,255,.10); --cyan-soft:rgba(106,203,255,.12);
  --sh:0 2px 6px rgba(20,26,40,.06),0 12px 30px rgba(20,26,40,.08);
  --sh-lg:0 24px 60px rgba(20,26,40,.22); --ring:0 0 0 3px var(--bg),0 0 0 6px var(--accent2);
  --warn-soft:#fdecea;
}
*{box-sizing:border-box}
html,body{height:100%}
/* page backdrop lives on <html> so the ambient ferro (#ferroBg, z-index:-1, a child of
   <body>) paints ABOVE it yet still below all .app content — else body's own bg box would
   occlude the z-index:-1 creature and you'd see no creature at all (the classic trap). */
/* FLUID ROOT (Ken 2026-06-30 "everything proportional never fixed"): the root font-size scales with the
   viewport, so every rem-based size grows/shrinks with the screen. rem here resolves against the browser
   default (16px), so this is ~13px on small screens → ~16.5px on large. All sizing is rem → all fluid. */
html{font-size:clamp(0.8rem, 0.26vw + 0.72rem, 1.03rem);
  background:
  radial-gradient(1200px 600px at 80% -10%,var(--cyan-soft),transparent 60%),
  radial-gradient(900px 500px at -10% 110%,var(--accent-soft),transparent 55%),
  var(--bg)}
body{margin:0;font-family:var(--ff);background:transparent;
  color:var(--txt);font-size:0.875rem;-webkit-font-smoothing:antialiased;overflow:hidden}
button{font:inherit;cursor:pointer;border:1px solid transparent;border-radius:var(--r-sm);padding:0.5625rem 0.9375rem;background:var(--accent);color:var(--accent-ink);font-weight:700;letter-spacing:.01em;transition:transform .14s var(--spring),filter .14s,box-shadow .16s}
button:hover{filter:brightness(1.08);transform:translateY(-1px)} button:active{transform:translateY(1px) scale(.99)}
button:focus-visible{outline:none;box-shadow:var(--ring)}
button.ghost{background:var(--surface);border-color:var(--line);color:var(--txt);font-weight:600}
button.ghost:hover{background:var(--surface2);border-color:var(--line2)}
button.subtle{background:transparent;border-color:transparent;color:var(--muted);font-weight:600;padding:0.5rem 0.625rem}
button.subtle:hover{background:var(--surface2);color:var(--txt)}
button.cyan{background:var(--accent2);color:#05222a}
button.sm{padding:0.375rem 0.6875rem;font-size:0.78125rem;border-radius:var(--r-xs)}
button:disabled{opacity:.45;cursor:not-allowed;filter:none;transform:none}
button.danger{background:transparent;border-color:var(--line);color:var(--block)}
input,select,textarea{font:inherit;background:var(--surface);color:var(--txt);border:1px solid var(--line);border-radius:var(--r-sm);padding:0.6875rem 0.8125rem;outline:none;width:100%;transition:border-color .14s,box-shadow .14s}
input:focus,textarea:focus,select:focus{border-color:var(--accent2);box-shadow:0 0 0 3px var(--cyan-soft)}
textarea{resize:vertical;line-height:1.5}
svg{display:block} .ic{width:1.125rem;height:1.125rem;stroke:currentColor;stroke-width:2;fill:none;stroke-linecap:round;stroke-linejoin:round}
::-webkit-scrollbar{width:0.625rem;height:0.625rem}::-webkit-scrollbar-thumb{background:var(--line2);border-radius:99px;border:2px solid transparent;background-clip:content-box}

/* ---- shell ---- */
.app{display:flex;flex-direction:column;height:100vh}
/* TEMPORARILY STRIPPED from the topbar (Ken: take away, stabilize, put back later).
   Remove this one rule to restore them. */
/* #cfgBtn UNHIDDEN 2026-07-04 (Ken: 'On far right on tool bar I want a settings wheel') —
   the rest of the minimal-topbar hide list stands. */
.conn,#freshBadge,#consoleBtn,#soundBtn,#themeBtn,.topbar .divider{display:none!important}
/* Safe-area (WO-A5): the base topbar also respects the notch — matters in native
   LANDSCAPE (width > the 640 mobile breakpoint but left/right/top insets exist).
   env() = 0 on desktop web, so nothing changes there. */
.topbar{display:flex;align-items:center;gap:0.75rem;flex:none;
  padding:env(safe-area-inset-top) max(1.125rem,env(safe-area-inset-right)) 0 max(1.125rem,env(safe-area-inset-left));
  height:calc(3.75rem + env(safe-area-inset-top));
  background:color-mix(in srgb,var(--surface) 80%,transparent);backdrop-filter:blur(14px);
  border-bottom:1px solid var(--line);z-index:20}
/* Brand lockup (Ken 2026-06-12): PlanOS wordmark 2x with a "Global Depth Systems product" line. */
.brand{display:flex;flex-direction:column;align-items:flex-start;gap:0;font-weight:800;letter-spacing:-.01em;cursor:pointer;line-height:1.04}
.brand .word{font-size:2.125rem;line-height:1}
.brand-sub{font-size:0.65625rem;font-weight:600;color:var(--muted);letter-spacing:0;margin-top:0.0625rem}
/* ── LOGO = a to-do line item, mid-cross (Ken 2026-06-18 "bullet list item themed... gonna be
   crossed off maybe but not quite"): a hand-drawn CHECKBOX before the wordmark + a red strike that
   cuts through "Plan" and TRAILS OFF before O·S. Both are SVG masks tinted by the theme (checkbox =
   currentColor ink, strike = --block red), so it works in both themes and needs no wordmark change. ── */
.brand .word{position:relative;display:inline-flex;align-items:center}
/* Logo checkbox (::before) REMOVED (Ken 2026-06-19 "Get rid of only this from logo") — the
   wordmark + red strike through "Plan" stay; the strike now starts at the start of "Plan". */
.logo-img{height:1.32em;display:block;width:auto}   /* image-logo slot (brand.js logoImage) — v5 check+wordmark lockup */
/* when the image logo is present, drop the decorative red strike (the lockup carries its own check) */
.brand .word:has(.logo-img)::after{content:none}
/* the red strike through "Plan" — restored with the Chewover revert (2026-07-04 PM) */
.brand .word::after{content:"";position:absolute;left:0;top:53%;transform:translateY(-50%);
  width:2.45em;height:.42em;pointer-events:none;background-color:var(--block,#b53b2d);
  -webkit-mask:url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%20120%2016%27%3E%3Cpath%20d%3D%27M4%209%20C%2026%206%2C%2052%2011%2C%2084%207%27%20fill%3D%27none%27%20stroke%3D%27black%27%20stroke-width%3D%275%27%20stroke-linecap%3D%27round%27%2F%3E%3C%2Fsvg%3E") left center/contain no-repeat;
          mask:url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%20120%2016%27%3E%3Cpath%20d%3D%27M4%209%20C%2026%206%2C%2052%2011%2C%2084%207%27%20fill%3D%27none%27%20stroke%3D%27black%27%20stroke-width%3D%275%27%20stroke-linecap%3D%27round%27%2F%3E%3C%2Fsvg%3E") left center/contain no-repeat}
.brand:hover .mark{transform:scale(1.05)}
.brand .mark{width:1.875rem;height:1.875rem;border-radius:10px;background:linear-gradient(135deg,var(--accent2),var(--accent));
  display:grid;place-items:center;color:#fff;font-size:0.9375rem;box-shadow:0 4px 14px var(--accent-soft)}
.brand b{color:var(--accent)} /* O = blue */
/* Mascot (helper character) — modest scale, breathing room, never grabs input. Used
   sparingly per docs/mascot.md ("mascot for warmth, system for work"). */
.mascot{display:block;width:7.5rem;height:auto;margin:0.625rem auto 0.375rem;pointer-events:none;user-select:none;
  filter:drop-shadow(0 8px 22px rgba(0,0,0,.28))}
.mascot-sm{width:4.5rem}.mascot-lg{width:10.75rem}
/* Whiskey — fixed corner companion: always visible, never covered by content. Sits above the
   page but BELOW the drawer/modal scrim (z 40) so dialogs still win. Tap to tuck to a peek + back. */
.buddy{position:fixed;top:calc(4.125rem + env(safe-area-inset-top));right:0.875rem;z-index:30;width:6rem;
  cursor:pointer;user-select:none;-webkit-tap-highlight-color:transparent;
  transition:transform .3s var(--spring),opacity .2s var(--ease)}
.buddy .mascot{width:6rem;margin:0;filter:drop-shadow(0 10px 18px rgba(0,0,0,.45))}
.buddy:hover{transform:translateY(-3px)}
.buddy.tucked{transform:translateX(70px);opacity:.9}        /* slides mostly off → small peek */
.buddy.tucked:hover{transform:translateX(54px);opacity:1}
.buddy.empty{display:none}                                  /* no art yet → no empty box */
body.auth-gate .buddy{display:none}                         /* hidden on the sign-in gate */
/* RETIRED (Ken 2026-06-15, circled it on the intake screen "I want what's red and circled gone"):
   the static corner astronaut-dog is redundant now that the live Ferro creature fills the mascot
   role. Hidden everywhere; the #buddy element + paintBuddy() machinery stay dormant (remove this
   line to bring it back). */
.buddy{display:none !important}
@media (prefers-reduced-motion: reduce){ .buddy,.buddy:hover{transition:none} }
@media(max-width:760px){ .buddy{width:4.5rem;top:calc(3.75rem + env(safe-area-inset-top));right:0.5rem}
  .buddy .mascot{width:4.5rem} .buddy.tucked{transform:translateX(52px)} }
.empty-line{text-align:center;color:var(--muted);font-size:.95rem;margin-top:0.25rem}
/* Faint space-dog backdrop on the launcher (feedback). Uses the moon scene for now; swap to
   a transparent cutout pose when one lands. Behind content, no input capture. */
/* No position override — use .screen's absolute inset:0 so the launcher (and its full-bleed
   backdrop) fills the WHOLE stage height; otherwise it shrinks to content and leaves a black
   bar below (feedback). */
/* ============ HOMESCREEN REDESIGN (work order 2026-06-13) ============
   Cinematic hero: Whiskey full-bleed (::before), a LEFT scrim for legibility, the red launch
   trajectory, and the PRIMARY ACTION = a solid goal bar + Plan-it button + chips (lower-left
   desktop / solid panel iPhone). Replaces the old dashed Plan tile + 3-widget wall.
   Asset slots: desktop bg = assets/mascot/launch_bg.jpg (1280x720), iPhone = moon_hero_scene.jpg
   (square, dog-centered). HOME SCREEN STILL SACRED — no Queue/Hero here. */
#scLaunch{background:#0A1424;overflow:hidden}
/* PHONE/TABLET: the launcher MUST scroll (K3 device bug 2026-07-05: uncapped chips grew
   the page past the fold and the old fixed-hero overflow:hidden left it STUCK — nothing
   owned the scroll). Desktop keeps hidden: the 2×2 grid fills 100% exactly. */
@media(max-width:1023px){ #scLaunch{overflow-y:auto} }
/* HERO PHOTO PANEL — a CONTAINED rounded card on the RIGHT (Ken 2026-06-13 "look closer to
   this concept... no red line, no moons/stars in the background"). The full-bleed photo and all
   decorations are gone; the background is plain dark. Mobile (@480) resets this to a top band. */
/* DOG PHOTO REMOVED (Ken 2026-06-19 "Get rid of this for now... thats where I want projects to live.
   Like a book shelf... Move them there since we have space and get rid of old location") — the right
   photo panel is gone; the BOOKSHELF (.lshelf) now occupies that space. */
#scLaunch::before{display:none}
/* No-op layer (kept for structure): the left is plain dark, so NO vignette/glow — the radial
   "smudge" read as an artifact (Ken 2026-06-13), removed. */
.lscrim{position:absolute;inset:0;z-index:1;pointer-events:none}
/* (Red launch-trajectory arc REMOVED — Ken 2026-06-13 "I want red line gone.") */
/* Content layer. */
#scLaunch .launch{position:relative;z-index:2;min-height:100%;display:block;padding:0}
/* Headline — TOP-LEFT over the scrim. */
/* Headline — TOP-LEFT, BIG. Fluid (clamp) so it fills the room on wide screens but shrinks before
   it can reach the photo panel; max-width is vw-capped for the same reason (Ken 2026-06-13 "why
   isn't this bigger, there's so much room"). */
.launchhead{position:absolute;top:2.5rem;left:3rem;z-index:2;text-align:left;max-width:min(40rem,46vw)}
.launchhead h1{margin:0;font-size:clamp(2.375rem,4.4vw,3.625rem);font-weight:500;line-height:1.06;letter-spacing:-.015em;text-shadow:0 2px 18px rgba(0,0,0,.45)}
#scLaunch .launchhead h1,#scLaunch .launchhead .launchsub{text-align:left}
.launchhead .launchsub{text-align:left;margin-top:0.875rem;color:#C4D2E4;font-size:1.125rem;font-weight:500}
.hl-red{color:var(--block,#EF5350)}
/* Recurring/habit step marker (once|recurring ticket type — Tier 1: label only). */
.recur{display:inline-flex;align-items:center;gap:0.1875rem;font-size:0.6875rem;font-weight:700;color:var(--accent2,#63D4FF);
  background:color-mix(in srgb,var(--accent2,#63D4FF) 14%,transparent);border-radius:7px;padding:0.125rem 0.4375rem;letter-spacing:.02em}
/* PRIMARY ACTION — anchored lower-left. */
.lstart{position:absolute;left:3rem;bottom:2.75rem;z-index:2;width:min(31.25rem,calc(100% - 6rem));display:flex;flex-direction:column}
/* GOAL COMPOSER — a generous multi-line context box (Ken 2026-06-14). Placeholder + chips keep it
   from being a blank wall; the footer carries the spark, the enter-hint, and the Plan-it button. */
.lgoal{display:flex;flex-direction:column;background:#101E33;border:1px solid #2A3C55;border-radius:16px;
  overflow:hidden;box-shadow:0 14px 38px rgba(0,0,0,.4)}
.lgoal:focus-within{border-color:#378ADD;box-shadow:0 14px 38px rgba(0,0,0,.4),0 0 0 3px color-mix(in srgb,#378ADD 28%,transparent)}
/* header strip: accent dot + live plan title + × clear */
.lgoal-head{display:flex;align-items:center;gap:0.625rem;padding:0.4375rem 1rem;background:rgba(55,138,221,.13);border-bottom:1px solid #2A3C55}   /* top bar ~50% shorter (Ken 2026-06-17) */
.lgoal-title{flex:1;min-width:0;color:#fff;font-weight:700;font-size:0.9375rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.lgoal-x{flex:none;background:none;border:none;color:#9FB0C4;font-size:1.375rem;line-height:1;cursor:pointer;padding:0 0.125rem}
.lgoal-x:hover{color:#fff}
/* WHITE input box, inset in the card */
.lgoal-in{display:block;width:auto;margin:1rem;min-height:7.5rem;resize:none;background:#fff;color:#13233A;
  border:none;border-radius:13px;outline:none;padding:1rem 1.125rem;font-size:2.125rem;line-height:1.45;font-weight:500;   /* 2× (Ken 2026-07-01 "font on here 2x"); placeholder stays 70% relative so it doubles too */
  font-family:inherit;box-shadow:0 2px 10px rgba(0,0,0,.25)}
.lgoal-in::placeholder{color:#7E8FA6;font-size:70%}   /* prompt 30% smaller (Ken 2026-06-17) — only the placeholder; typed text unchanged */
.lgoal-foot{display:flex;align-items:center;gap:0.625rem;padding:0 1rem 0.875rem}
.lgoal-btn{flex:none;background:#378ADD;color:#fff;border:none;border-radius:10px;padding:0.6875rem 1.25rem;font-size:1.3125rem;font-weight:700;cursor:pointer}   /* "Plan it →" 2× (Ken 2026-07-01 "font on here 2x") */
.lgoal.is-empty .lgoal-btn{background:none;color:#5A6B82;box-shadow:none}   /* dim "Plan it" until there's a goal */
.lgoal-btn:hover{background:#2f79c4}
.lgoal-btn:disabled{opacity:.65;cursor:default}
.lgoal-btn .lbl-m{display:none}
.lhint{color:#7F93AB;font-size:0.78125rem;margin:0.5625rem 0.125rem 0}
.lhint:empty{display:none}
.lchips{display:flex;flex-direction:column;align-items:flex-start;gap:0.5625rem;margin-top:0.875rem;
  max-height:13rem;overflow-y:auto;overflow-x:hidden;padding-right:0.25rem;
  scrollbar-width:thin;scrollbar-color:#34527a transparent;overscroll-behavior:contain}
.lchips::-webkit-scrollbar{width:0.5rem}
.lchips::-webkit-scrollbar-thumb{background:#34527a;border-radius:8px;border:2px solid transparent;background-clip:padding-box}
.lchips::-webkit-scrollbar-track{background:transparent}
.lchips:empty{display:none}
.lchip{background:rgba(16,30,51,.66);border:1px solid #2A3C55;color:#C4D2E4;border-radius:999px;
  padding:0.5rem 0.9375rem;font-size:0.875rem;font-weight:600;cursor:pointer;white-space:nowrap}
.lchip:hover{border-color:#378ADD;color:#fff}
/* BOOKSHELF (Ken 2026-06-19 "thats where I want projects to live. Like a book shelf... Move them
   there since we have space") — saved plans live on the RIGHT, where the dog photo was. A vertical
   shelf of "books": each plan is a card stacked top-to-bottom with a coloured spine, scrolls if many.
   The header sits OUTSIDE #bigCol so the render (which clears #bigCol) never wipes it. iPhone (@480)
   drops it back into the normal stacked flow. */
/* RIGHT COLUMN (Ken 2026-06-19 "I want this [hero animation] literally on the home page on right"):
   the looping "Make it easier" animation up top, the plans bookshelf below it. */
.lright{position:absolute;top:6rem;right:2.625rem;bottom:2.75rem;width:min(38%,30rem);z-index:2;
  display:flex;flex-direction:column;gap:1.125rem}
.lart{flex:none;width:100%;aspect-ratio:680/420;display:block;border-radius:14px;border:none;
  pointer-events:none;box-shadow:0 16px 40px rgba(20,12,4,.4)}   /* <object> renders the SVG as a document so its CSS loop runs; decorative → no clicks */
.lshelf{flex:1 1 auto;min-height:0;display:flex;flex-direction:column;gap:0.75rem}
.lshelf:has(.lplans:empty){display:none}                 /* nothing to shelve → no empty frame (the animation stays) */
/* (The desktop empty-state "hug the sketch" override was RETIRED 2026-06-22 with the 2×2 grid — the
   sketch is now its own grid cell at its natural aspect ratio, so there's no tall empty panel to fill.) */
.lshelf-head{flex:none;display:flex;align-items:center;font-size:0.8125rem;font-weight:800;letter-spacing:.06em;text-transform:uppercase;
  color:#9FB0C4;padding-left:0.125rem}
/* "Clear all" (Ken 2026-06-24): wipe every ACTIVE plan from My plans — pushed to the far right of the header. */
.lshelf-clear{margin-left:auto;border:1px solid var(--line,#2A3C55);background:transparent;color:#9FB0C4;
  font:inherit;font-size:0.6875rem;letter-spacing:.04em;text-transform:uppercase;padding:0.1875rem 0.5625rem;border-radius:7px;
  cursor:pointer;line-height:1}
.lshelf-clear[hidden]{display:none}
.lshelf-clear:hover{background:var(--bad,#EF5350);color:#fff;border-color:var(--bad,#EF5350)}
.lplans{flex:1;min-height:0;display:flex;flex-direction:column;gap:0.75rem;width:100%;margin:0;
  overflow-y:auto;overflow-x:hidden;padding:0.75rem 0.375rem 0.875rem;scroll-padding-top:12px;
  scrollbar-width:thin;scrollbar-color:#34527a transparent;overscroll-behavior:contain}
.lplans::-webkit-scrollbar{width:0.5rem}
.lplans::-webkit-scrollbar-thumb{background:#34527a;border-radius:8px;border:2px solid transparent;background-clip:padding-box}
.lplans::-webkit-scrollbar-track{background:transparent}
.lplans:empty{display:none}
/* CAPTURE LANE — quick-task checklist atop the launcher shelf (Ken 2026-07-09). Fluid sizing only
   (px is hairline borders + border-radius, matching .planrow). Dark-theme colours; body.ink overrides in ink.css. */
.capcard{flex:0 0 auto;display:flex;flex-direction:column;gap:0.3rem;margin-bottom:0.4rem}
.caphead{display:flex;align-items:baseline;gap:0.5rem;font-size:0.75rem;font-weight:800;letter-spacing:.05em;text-transform:uppercase;color:#9FB0C4;opacity:.85;padding-left:0.125rem}
.caplist{display:flex;flex-direction:column;gap:0.2rem}
.caprow{display:flex;align-items:center;gap:0.5rem;padding:0.3rem 0.4rem;border-radius:9px}
.caprow:hover{background:rgba(16,30,51,.5)}
.capchk{flex:0 0 auto;width:1.15rem;height:1.15rem;border-radius:50%;border:2px solid currentColor;background:transparent;color:#9FB0C4;opacity:.7;cursor:pointer;padding:0}
.capchk:hover{opacity:1;color:#4F9E8C}
.captitle{flex:1 1 auto;font-size:0.95rem;line-height:1.3;color:inherit;overflow-wrap:anywhere}
.capbreak{flex:0 0 auto;font:inherit;font-size:0.72rem;padding:0.15rem 0.5rem;border-radius:8px;border:1px solid var(--accent,#378ADD);background:transparent;color:var(--accent,#378ADD);cursor:pointer;white-space:nowrap}
.capbreak:hover{background:var(--accent,#378ADD);color:#fff}
.capx{flex:0 0 auto;font:inherit;font-size:0.8rem;background:transparent;border:none;color:#9FB0C4;opacity:.5;cursor:pointer;padding:0 0.2rem}
/* per-row delete ×, header Clear all, and inline-edit field (Ken 2026-07-10) */
.capdel{flex:0 0 auto;font:inherit;font-size:1.375rem;line-height:1;background:transparent;border:none;color:#9FB0C4;opacity:.55;cursor:pointer;padding:0 0.3rem}
.capdel:hover{opacity:1;color:var(--bad,#EF5350)}
.cap-clear{margin-left:auto;flex:none;font:inherit;font-size:0.7rem;letter-spacing:.04em;text-transform:uppercase;background:none;border:none;color:#9FB0C4;opacity:.8;cursor:pointer;padding:0 0.2rem}
.cap-clear:hover{opacity:1;color:var(--bad,#EF5350)}
.cap-add{flex:none;font:inherit;font-size:1.6rem;line-height:1;background:none;border:none;color:#9FB0C4;opacity:.7;cursor:pointer;padding:0 0.15rem}
.cap-add:hover{opacity:1;color:var(--accent)}
.captitle{cursor:text}
input.capedit{border-bottom:2px solid var(--accent,#378ADD);border-radius:0}
.capx:hover{opacity:1}
.capadd{gap:0.5rem;margin-top:0.1rem}
.capplus{flex:0 0 auto;width:1.15rem;text-align:center;color:#9FB0C4;opacity:.6;font-size:1rem;line-height:1}
.capinput{flex:1 1 auto;font:inherit;font-size:0.95rem;background:transparent;border:none;outline:none;color:inherit;padding:0.2rem 0}
.capinput::placeholder{color:#9FB0C4;opacity:.6}
.caprow.capdone{opacity:.6}
.caprow.capdone .captitle{text-decoration:line-through}
.caprow.capdone .capchk{opacity:1;background:#4F9E8C;border-color:#4F9E8C}
/* Estimate chip on the hero step (C3, Ken 2026-07-08) — soft time range, never a countdown. */
.cs-est{display:inline-block;margin:0.1rem 0 0.35rem;font-size:0.8rem;color:#9FB0C4;opacity:.9;letter-spacing:.01em}
.cs-est.big{color:#E0A23C;opacity:1}
/* PLAN CONTEXT TAGS (Ken 2026-07-09 "House/Work" — filter chips + a per-plan tag). Fluid only. */
.planfilters{flex:0 0 auto;display:flex;flex-wrap:wrap;gap:0.4rem;padding:0.1rem 0.25rem 0.5rem}
.pfchip{font:inherit;font-size:0.82rem;padding:0.2rem 0.7rem;border-radius:999px;border:1px solid #2A3C55;background:transparent;color:#9FB0C4;cursor:pointer}
.pfchip.on{background:#378ADD;border-color:#378ADD;color:#fff}
.plantag{position:relative;align-self:flex-start;margin-top:0.35rem;font:inherit;font-size:0.72rem;padding:0.1rem 0.5rem;border-radius:999px;border:1px dashed #2A3C55;background:transparent;color:#8298b4;cursor:pointer}
.plantag.set{border-style:solid;border-color:#4F9E8C;color:#bfe3d6}
.ctxpick{position:absolute;left:1.1rem;z-index:30;margin-top:0.3rem;display:flex;flex-direction:column;gap:0.1rem;background:#0f1e33;border:1px solid #2A3C55;border-radius:0.6rem;padding:0.3rem;box-shadow:0 8px 24px rgba(0,0,0,.4)}
.ctxopt{font:inherit;font-size:0.85rem;text-align:left;padding:0.3rem 0.6rem;border-radius:0.4rem;border:none;background:transparent;color:#dbe6f2;cursor:pointer;white-space:nowrap}
.ctxopt:hover{background:#1b3055}
.ctxopt.clear{color:#e0857a}
/* Hide the "Archived (N)" section on the launcher (Ken 2026-07-09 "get rid of this just visually, I don't
   like it there") — archiving + the trophy wall still work; the collapsible row just isn't shown. */
#scLaunch .arch-head, #scLaunch .planrow.is-arch{display:none!important}
/* Hide the empty context tags on plan cards (Ken 2026-07-10 "get rid of these for now") — the tag
   machinery stays; the little chip just isn't shown. */
#scLaunch .plantag{display:none!important}
/* Signed-in user label in the topbar next to the arrows (Ken 2026-07-09 — email prefix, "admin", "kshay"). */
.whoami{font-size:0.82rem;font-weight:700;color:var(--muted);padding:0 0.15rem;white-space:nowrap}   /* show the FULL email — no max-width/ellipsis truncation (Ken 2026-07-10) */
.whoami[hidden]{display:none}
/* CONTEXTUAL NAV (Ken 2026-07-10): _updateNav toggles [hidden] on the nav buttons per screen — this
   makes the attribute actually hide them (the .nav-arrow display would otherwise win). The home glyph
   sits between the big chevrons, a touch smaller so it doesn't dominate. */
.topbar button[hidden]{display:none!important}
#homeBtn.nav-arrow{font-size:2.6rem}
/* PERSONAL API KEYS in Settings (Ken 2026-07-10) — a clean, professional panel: header row, divider
   lines, monospace key prefixes, a copy-once reveal. Buttons get real treatment in ink.css. */
.tok-list{display:flex;flex-direction:column}
.tok-row{display:flex;align-items:center;gap:0.75rem;padding:0.7rem 1rem;border-top:1px solid color-mix(in srgb,var(--line) 55%,transparent)}
.tok-meta{display:flex;flex-direction:column;gap:0.15rem;flex:1;min-width:0}
.tok-meta b{font-weight:650;color:var(--txt)}
.tok-pre{font-size:0.72rem;letter-spacing:0.02em;color:var(--muted);font-family:ui-monospace,Menlo,Consolas,monospace;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tok-rev{margin-left:auto;flex:none}
.tok-empty{color:var(--muted);font-size:0.85rem;padding:0.75rem 1rem;border-top:1px solid color-mix(in srgb,var(--line) 55%,transparent)}
.tok-new{border-top:1px solid color-mix(in srgb,var(--line) 55%,transparent)}
.tok-gen{display:flex;gap:0.5rem;align-items:center;padding:0.7rem 1rem;flex-wrap:wrap}
.tok-gen .set-in{flex:1;min-width:9rem}
.tok-reveal{display:flex;flex-wrap:wrap;gap:0.6rem;align-items:center;padding:0.75rem 1rem}
.tok-reveal code{flex:1 1 100%;overflow-x:auto;white-space:nowrap;padding:0.5rem 0.6rem;border-radius:0.4rem;font-family:ui-monospace,Menlo,Consolas,monospace;font-size:0.8rem}
.tok-warn{width:100%;display:flex;align-items:center;gap:0.35rem;font-size:0.78rem;font-weight:700;color:var(--block,#b53b2d)}
.planrow{position:relative;flex:0 0 auto;width:100%;min-height:3.75rem;scroll-snap-align:none;
  display:flex;flex-direction:column;justify-content:center;
  padding:0.875rem 2.125rem 0.875rem 1.125rem;border-radius:11px;text-align:left;
  background:rgba(16,30,51,.62);border:1px solid #2A3C55;border-left:4px solid #378ADD;cursor:pointer;
  transition:border-color .12s}
.planrow:hover{border-color:#378ADD}   /* no hover transform — it fights the baked layout-editor transform (FLYWHEEL) */
/* coloured book spines — a cheerful shelf (cycles through the palette) */
.planrow:nth-child(6n+1){border-left-color:#E0A23C}
.planrow:nth-child(6n+2){border-left-color:#378ADD}
.planrow:nth-child(6n+3){border-left-color:#D9694C}
.planrow:nth-child(6n+4){border-left-color:#4F9E8C}
.planrow:nth-child(6n+5){border-left-color:#8E6FC4}
.planrow:nth-child(6n+6){border-left-color:#C45C86}
.planrow .nm{font-weight:600;color:#fff;font-size:0.9375rem;line-height:1.3;white-space:normal;
  display:-webkit-box;-webkit-line-clamp:2;line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
/* Delete ✕ = a BIG, easy hit target (Ken 2026-06-30 "make the X much larger, I keep missing it and
   opening the plan instead"): 22px glyph in a 38px square, clearly visible, red on hover. */
.planrow .del{position:absolute;top:0.375rem;right:0.375rem;opacity:.6;flex:none;color:#9FB0C4;font-size:1.375rem;line-height:1;
  width:2.375rem;height:2.375rem;display:flex;align-items:center;justify-content:center;border-radius:9px;z-index:2}
.planrow .del:hover{opacity:1;color:var(--bad,#EF5350);background:color-mix(in srgb,var(--bad,#EF5350) 13%,transparent)}
.planrow.new{border-style:dashed;color:#9FB0C4;font-weight:700}
.planrow.new .pr-plus{font-size:1rem;line-height:1;width:1.5rem;text-align:center}
/* COMPLETE plan → crossed out here (Ken 2026-06-22 "when a plan is complete it should be crossed out").
   The name strikes red; the row stays clickable + openable. */
.planrow .nm.struck{text-decoration:line-through;text-decoration-color:var(--block,#EF5350);
  text-decoration-thickness:2px;color:var(--muted,#9FB0C4)}
/* 📥 Archive (Ken 2026-06-22 "ability to Archive it") — a quiet top-right icon, left of the ✕ delete. */
.planrow .arch{position:absolute;top:0.375rem;right:3rem;opacity:.5;flex:none;font-size:1rem;line-height:1;cursor:pointer;
  width:2.125rem;height:2.375rem;display:flex;align-items:center;justify-content:center}
.planrow .arch:hover{opacity:1}
/* ARCHIVED footer: a collapsible "Archived (N)" group — hidden from the active list but never lost. */
.planrow.arch-head{flex-direction:row;align-items:center;justify-content:space-between;min-height:0;
  padding:0.5625rem 0.875rem;background:none;border:1px dashed var(--line,#2A3C55);border-left-width:1px;
  color:var(--muted,#9FB0C4);font-weight:700;opacity:.85}
.planrow.arch-head .nm{color:var(--muted,#9FB0C4);font-weight:700;-webkit-line-clamp:1;line-clamp:1}
.arch-chev{font-size:0.75rem;opacity:.7}
#bigCol .planrow.is-arch{display:none}
#bigCol.show-arch .planrow.is-arch{display:flex}
.planrow.is-arch{opacity:.72}
.planrow.is-arch .arch{right:0.625rem}
/* "+" in the "My plans" header → the template picker (start a fresh plan from a finished one). */
.lshelf-add{margin-left:0.5rem;width:1.375rem;height:1.375rem;border-radius:7px;border:1px solid var(--line,#2A3C55);
  background:var(--accent-soft,rgba(55,138,221,.14));color:var(--txt,#C4D2E4);font-size:0.9375rem;font-weight:800;
  line-height:1;cursor:pointer;vertical-align:middle;padding:0;display:inline-flex;align-items:center;justify-content:center}
.lshelf-add:hover{background:var(--accent,#378ADD);color:#fff;border-color:var(--accent,#378ADD)}
/* legacy launcher pieces retired by the redesign. */
#littleCol,.buddywidget,.planwall{display:none}
body[data-screen="launcher"] .buddy{display:none}
/* TABLET 481–1023: cap the action width, ease the headline. */
@media(max-width:1023px){ .launchhead{max-width:min(27.5rem,46vw)} .launchhead h1{font-size:clamp(1.75rem,4vw,2.625rem)} .lstart{width:min(26.25rem,calc(100% - 4rem))} }
/* TABLET BAND (481-1023) — the desktop 2-zone absolute layout (composer lower-left + bookshelf
   upper-right) doesn't fit below ~822px → the cards overlapped the composer. Stack the launcher to
   static flow here, like phone does (responsive-audit fix, Ken 2026-06-19). */
@media (min-width:481px) and (max-width:1023px){
  /* TABLET: CENTERED column that USES the width (Ken 2026-07-11 audit-wall pass: the old left-hugging
     35rem caps left the right half of an iPad dead — "not taking advantage of all the space"). */
  #scLaunch .launch{position:static;display:block;padding:2.125rem 1.875rem 3rem;min-height:0;
    max-width:46rem;margin:0 auto}
  .launchhead{position:static;left:auto;top:auto;max-width:100%;margin:0 0 1.125rem}
  .lstart{position:static;left:auto;bottom:auto;width:100%}
  .lright{position:static;width:auto;margin:1.625rem 0 0}
  .lart{max-width:none}
  .lshelf{flex:none;margin:1.125rem 0 0;gap:0.625rem}
  .lplans{flex:none;max-height:48vh;overflow-y:auto}   /* bounded + scrollable so a long list fits the page (Ken 2026-06-24) */
}
/* iPHONE ≤480: RECOMPOSED (not a squished desktop) — image top band + solid panel below. */
@media(max-width:480px){
  #scLaunch{background:#0C1828}
  #scLaunch::before{display:none}   /* dog photo gone on mobile too (Ken 2026-06-19) — no top band */
  .lscrim{display:none}
  #scLaunch .launch{position:static;display:block;
    padding:calc(1.125rem + env(safe-area-inset-top)) 1rem calc(1.375rem + env(safe-area-inset-bottom))}
  .launchhead{position:static;left:auto;top:auto;max-width:100%;margin:0 0 1rem}
  .launchhead h1{font-size:1.3125rem}
  .launchhead .launchsub{font-size:0.8125rem}
  .lstart{position:static;left:auto;bottom:auto;width:100%;display:block}
  /* keep the card (header + white input) on iPhone; shorten it + full-width button */
  .lgoal-in{margin:0.875rem;min-height:5.75rem;padding:0.875rem}
  .lgoal-foot{padding:0 0.875rem 0.875rem}
  .lgoal-btn{flex:1 1 auto;width:auto;min-width:0;text-align:center;padding:0.875rem}   /* width:100% inside the padded flex footer spilled well past the right edge (audit wall, 2026-07-11) */
  .lgoal-btn .lbl-d{display:none}.lgoal-btn .lbl-m{display:inline}
  .lchips{margin-top:0.875rem;max-height:none;overflow-y:visible}   /* phone: no cap — a capped list left a clipped-chip sliver (K3 2026-07-05); the page scrolls */
  /* iPhone: the animation + bookshelf drop into the normal stacked flow under the composer. */
  .lright{position:static;width:auto;margin:1.25rem 0 0;gap:0.875rem;z-index:2}
  .lshelf{flex:none;width:auto;margin:0;gap:0.5rem}
  .lshelf-head{font-size:0.75rem}
  .lplans{flex:none;flex-direction:column;width:auto;overflow-y:auto;max-height:52vh;margin:0;padding:0 0.125rem}   /* scrollable, fits the screen (Ken 2026-06-24) */
  .planrow{flex-direction:row;align-items:center;width:auto;min-height:0;height:auto;gap:0.625rem;padding:0.6875rem 0.8125rem}
  .planrow .nm{display:block;-webkit-line-clamp:1;line-clamp:1;white-space:nowrap;text-overflow:ellipsis;flex:1}
  .planrow .del{position:static;top:auto;right:auto}
}
/* Fresh Mode badge — visible proof that browser caching is OFF (no-store). Driven by
   the ACTUAL server Cache-Control header so it can't lie; disappears when caching
   is re-enabled. Amber so it reads as a deliberate dev affordance. */
.freshbadge{display:inline-flex;align-items:center;gap:0.3125rem;cursor:help;
  padding:0.25rem 0.5625rem;border-radius:999px;font-size:0.6875rem;font-weight:800;letter-spacing:.02em;
  color:#3a2a00;background:linear-gradient(135deg,#ffd24d,#ffb020);
  border:1px solid #e69a00;box-shadow:0 2px 8px rgba(255,176,32,.25);white-space:nowrap}
.freshbadge:hover{filter:brightness(1.05)}
.brand em{color:var(--block);font-style:normal} /* S = coral red (V4 wordmark) */
.divider{width:0.0625rem;height:1.75rem;background:var(--line)}
.crumb{display:flex;align-items:center;gap:0.5rem;color:var(--muted);font-weight:600;min-width:0}
.crumb .pj{color:var(--txt);max-width:17.5rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* Admin-only small print: the LLM models actually running (Ken 2026-06-30 "we use several models"). */
.admin-models{font-size:0.6875rem;line-height:1;color:var(--muted);opacity:.7;font-family:ui-monospace,Menlo,Consolas,monospace;letter-spacing:0.0125rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:22.5rem;margin-left:0.375rem}
.spacer{flex:1}
.conn{display:flex;align-items:center;gap:0.4375rem;font-size:0.75rem;color:var(--muted);padding:0.375rem 0.6875rem;border:1px solid var(--line);border-radius:999px}
.dot{width:0.5rem;height:0.5rem;border-radius:50%;background:var(--faint)} .dot.ok{background:var(--done);box-shadow:0 0 0 3px color-mix(in srgb,var(--done) 25%,transparent)} .dot.bad{background:var(--block)}
.stage{flex:1;min-height:0;position:relative;overflow:hidden}
.screen{position:absolute;inset:0;overflow:auto;opacity:0;transform:translateY(10px);pointer-events:none;transition:opacity .26s var(--ease),transform .26s var(--ease)}
.screen.on{opacity:1;transform:none;pointer-events:auto}

/* ============ LAUNCHER (Switch home row) ============ */
.launch{min-height:100%;display:flex;flex-direction:column;padding:2.125rem 2.5rem 3.75rem}
.launch h1{font-size:2.125rem;font-weight:800;letter-spacing:-.02em;margin:0.625rem 0 0.5rem;text-align:center}
.launch .launchsub{color:var(--muted);font-size:0.9375rem;font-weight:600;text-align:center;margin:0 0 2.125rem}
.launch .lead{color:var(--muted);font-size:0.9375rem;margin:0 0 1.875rem}
.tiles{display:flex;gap:1.375rem;flex-wrap:wrap;align-items:stretch;justify-content:center}
.tile{position:relative;width:14.375rem;height:11.625rem;border-radius:var(--r);border:1px solid var(--line);
  background:var(--surface);box-shadow:var(--sh);cursor:pointer;overflow:hidden;
  transition:transform .2s var(--spring),box-shadow .2s;animation:pop .42s var(--spring) both}
.tile:hover{transform:translateY(-6px) scale(1.025)}
.tile:active{transform:translateY(-2px) scale(1.0)}
.tile:focus-visible{outline:none;box-shadow:var(--ring)}
.tile .cap{position:absolute;inset:0;padding:1.125rem;display:flex;flex-direction:column;justify-content:flex-end;gap:0.1875rem;pointer-events:none}
.tile .art{position:absolute;top:0;left:0;right:0;height:6rem;background:linear-gradient(135deg,var(--g1,#3b9dff),var(--g2,#63D4FF))}
.tile .art:after{content:"";position:absolute;inset:0;background:radial-gradient(120px 80px at 80% 10%,rgba(255,255,255,.35),transparent 70%)}
.tile .glyph{position:absolute;top:1.5rem;left:1.25rem;color:rgba(255,255,255,.95);font-size:2.125rem;font-weight:800;text-shadow:0 2px 8px rgba(0,0,0,.25)}
.tile .k{font-family:ui-monospace,SFMono-Regular,monospace;font-size:0.6875rem;color:var(--muted);font-weight:700}
/* plan-type label + a subtle colored left edge (little = cyan, big = violet) */
.tile .ptype{font-size:0.625rem;font-weight:800;letter-spacing:.12em;text-transform:uppercase}
.tile .ptype.pt-little{color:#7fe0ef}
.tile .ptype.pt-big{color:#c79bff}
.tile.pt-little::before,.tile.pt-big::before{content:"";position:absolute;left:0;top:0;bottom:0;width:0.25rem;z-index:3;border-radius:var(--r) 0 0 var(--r)}
.tile.pt-little::before{background:#7fe0ef}
.tile.pt-big::before{background:#c79bff}
.tile .nm{font-size:1rem;font-weight:750;letter-spacing:-.01em;line-height:1.2;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.tile.new{display:grid;place-items:center;background:
  repeating-linear-gradient(135deg,transparent,transparent 11px,color-mix(in srgb,var(--accent) 6%,transparent) 11px,color-mix(in srgb,var(--accent) 6%,transparent) 22px),var(--surface);
  border:2px dashed color-mix(in srgb,var(--accent) 45%,var(--line))}
.tile.new .plus{width:3.625rem;height:3.625rem;border-radius:16px;background:var(--accent);color:#fff;display:grid;place-items:center;
  font-size:1.875rem;font-weight:300;box-shadow:0 8px 22px var(--accent-soft);transition:transform .2s var(--spring)}
.tile.new:hover .plus{transform:scale(1.08)}
.tile.new .lbl{position:absolute;bottom:2rem;left:0;right:0;text-align:center;font-weight:750;color:var(--accent)}
/* consistent plan icons: scale shown by NUMBER of blocks (little = 1, big = 4) */
.tile.new .plus .bk,.tile.goal .plus .bk{background:#fff;border-radius:5px;display:block}
.tile.new .plus .bk{width:1.625rem;height:1.625rem}
.tile.goal .plus{grid-template-columns:1fr 1fr;gap:0.3125rem;place-content:center}
.tile.goal .plus .bk{width:0.8125rem;height:0.8125rem;background:#05222a}
/* concise example under the Little/Big plan tiles — small + muted, never crowds it */
.tile.new .ex,.tile.goal .ex,.tile.tpl .ex{position:absolute;bottom:0.875rem;left:0;right:0;text-align:center;font-size:0.6875rem;color:var(--muted);font-weight:600}
/* FB-1: dynamic clickable idea chips on the big-goal screen (replaces static example text) */
.ideas{display:flex;flex-wrap:wrap;gap:0.5rem;margin:0.625rem 0 0.125rem}
.ideas .hint{flex-basis:100%;font-size:0.6875rem;color:var(--muted);font-weight:700;letter-spacing:.02em;margin-bottom:0.0625rem}
.idea{font:inherit;font-size:0.8125rem;color:var(--accent2);background:var(--surface2);border:1px solid var(--line2);border-radius:999px;padding:0.4375rem 0.8125rem;cursor:pointer;text-align:left;transition:transform .12s ease,background .12s ease,border-color .12s ease}
.idea:hover{background:color-mix(in srgb,var(--accent2) 12%,var(--surface2));border-color:var(--accent);transform:translateY(-1px)}
.idea:active{transform:translateY(0)}
.idea.more{color:var(--muted);border-style:dashed}
@media (prefers-reduced-motion: reduce){.idea{transition:none}.idea:hover{transform:none}}
/* "From template" launcher tile + the template picker rows */
.tile.tpl{display:grid;place-items:center;background:
  repeating-linear-gradient(135deg,transparent,transparent 11px,color-mix(in srgb,var(--muted) 7%,transparent) 11px,color-mix(in srgb,var(--muted) 7%,transparent) 22px),var(--surface);
  border:2px dashed var(--line)}
/* "Sit with me" launcher tile — body-double is the differentiator, so it's first-class, not buried */
.tile.sit{display:grid;place-items:center;background:
  repeating-linear-gradient(135deg,transparent,transparent 11px,color-mix(in srgb,var(--accent) 9%,transparent) 11px,color-mix(in srgb,var(--accent) 9%,transparent) 22px),var(--surface);
  border:2px dashed color-mix(in srgb,var(--accent) 45%,var(--line))}
.tile.sit .plus{width:3.625rem;height:3.625rem;border-radius:16px;background:var(--surface2);display:grid;place-items:center;font-size:1.625rem}
.tile.sit .lbl{position:absolute;bottom:2rem;left:0;right:0;text-align:center;font-weight:750;color:var(--txt)}
.tile.sit .ex{position:absolute;bottom:0.875rem;left:0;right:0;text-align:center;font-size:0.6875rem;color:var(--muted);font-weight:600}
.tile.tpl .plus{width:3.625rem;height:3.625rem;border-radius:16px;background:var(--surface2);display:grid;place-items:center;font-size:1.625rem}
.tile.tpl .lbl{position:absolute;bottom:2rem;left:0;right:0;text-align:center;font-weight:750;color:var(--txt)}
/* Template modal "make a plan" composer — a mirror of the launcher door (Ken 2026-07-10). */
.tpl-compose{display:flex;flex-direction:column;gap:0.4rem}
.tpl-goal-in{width:100%;box-sizing:border-box;font:inherit;font-size:1rem;padding:0.6rem 0.7rem;border:1.5px solid var(--line2,#cdbfa2);border-radius:0.6rem;background:var(--surface,#fff);color:inherit;resize:none}
.tpl-goal-foot{display:flex;justify-content:flex-end}
.tpl-or{font-size:0.8rem;color:var(--muted,#9FB0C4);text-align:center;margin:0.55rem 0 0.5rem}
.tplrow{display:flex;align-items:center;justify-content:space-between;gap:0.625rem;padding:0.6875rem 0.8125rem;border:1px solid var(--line);border-radius:11px}
.tplrow+.tplrow{margin-top:0.5rem}
.tplrow .tpl-nm{font-weight:700;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* "Map a big goal" — a first-class sibling tile (cyan), not a bolted-on bar. */
.tile.goal{display:grid;place-items:center;background:
  repeating-linear-gradient(135deg,transparent,transparent 11px,color-mix(in srgb,var(--accent2) 7%,transparent) 11px,color-mix(in srgb,var(--accent2) 7%,transparent) 22px),var(--surface);
  border:2px dashed color-mix(in srgb,var(--accent2) 45%,var(--line))}
.tile.goal .plus{width:3.625rem;height:3.625rem;border-radius:16px;background:var(--accent2);color:#05222a;display:grid;place-items:center;
  font-size:1.6875rem;box-shadow:0 8px 22px var(--cyan-soft);transition:transform .2s var(--spring)}
.tile.goal:hover .plus{transform:scale(1.08)}
.tile.goal .lbl{position:absolute;bottom:2rem;left:0;right:0;text-align:center;font-weight:750;color:var(--accent2)}
/* Launcher plan tiles colored (feedback): Big = red (a real undertaking), Little = blue. */
.tile.plan-red .plus{background:var(--accent);color:#fff}
.tile.plan-red .plus .bk{background:#fff}
.tile.plan-red .lbl{color:var(--accent)}
.tile.plan-blue .plus{background:var(--accent);color:#fff}
.tile.plan-blue .plus .bk{background:#fff}
.tile.plan-blue .lbl{color:var(--accent)}
.tiledel{position:absolute;top:0.625rem;right:0.625rem;z-index:5;width:1.875rem;height:1.875rem;border-radius:8px;display:grid;place-items:center;
  background:rgba(0,0,0,.42);color:#fff;font-size:0.875rem;font-weight:700;opacity:0;transform:scale(.85);
  transition:opacity .15s,transform .15s var(--spring);backdrop-filter:blur(3px);pointer-events:auto}
.tile:hover .tiledel,.tile:focus-within .tiledel{opacity:1;transform:scale(1)}
.tiledel:hover{background:var(--accent)}
.tiles .tile:nth-child(1){animation-delay:.02s}.tiles .tile:nth-child(2){animation-delay:.06s}
.tiles .tile:nth-child(3){animation-delay:.10s}.tiles .tile:nth-child(4){animation-delay:.14s}
.tiles .tile:nth-child(5){animation-delay:.18s}.tiles .tile:nth-child(n+6){animation-delay:.22s}
.launch .empty-hint{color:var(--faint);font-size:0.8125rem;margin-top:1.625rem}

/* ============ WIZARD ============ */
.wrap{max-width:61.25rem;margin:0 auto;padding:1.875rem 1.75rem 5rem}
.rail{display:flex;align-items:center;gap:0.625rem;margin:0.25rem 0 1.625rem;flex-wrap:wrap}
.step{display:flex;align-items:center;gap:0.5625rem;color:var(--faint);font-weight:700;font-size:0.8125rem}
.step .b{width:1.625rem;height:1.625rem;border-radius:50%;display:grid;place-items:center;font-size:0.75rem;
  background:var(--surface2);border:1px solid var(--line);transition:.25s var(--spring)}
.step.on{color:var(--txt)} .step.on .b{background:var(--accent);color:#fff;border-color:var(--accent);transform:scale(1.08)}
.step.done .b{background:var(--done);color:#06270d;border-color:var(--done)}
.rail .seg{flex:1;height:0.1875rem;border-radius:99px;background:var(--line);min-width:1.5rem;max-width:5.625rem}
.rail .seg.fill{background:var(--accent2)}
.q{font-size:1.5625rem;font-weight:800;letter-spacing:-.02em;margin:0 0 0.375rem}
.qsub{color:var(--muted);font-size:0.875rem;margin:0 0 1.375rem;line-height:1.55}
.fieldrow{display:flex;gap:1rem;flex-wrap:wrap;align-items:flex-end}
.fieldrow .f{flex:1;min-width:12.5rem}
.lbl{display:block;font-size:0.75rem;font-weight:700;color:var(--muted);margin-bottom:0.375rem;text-transform:uppercase;letter-spacing:.05em}
.preview{margin-top:1.5rem}
.wizfoot{margin-top:1.625rem;display:flex;gap:0.75rem;align-items:center}
/* ===== GOAL-ENTRY SCREEN (work order 2026-06-13): focused, vertically-centered step 1.
   Tokens inherited from the homescreen redesign. iPhone recomposes to a bottom-anchored
   full-width Continue. ===== */
.goalstep{position:relative;min-height:calc(100dvh - 8.125rem);display:flex;flex-direction:column;
  align-items:center;justify-content:center;text-align:center;padding:1.25rem 0}
.goalcol{width:100%;max-width:35rem;display:flex;flex-direction:column;align-items:center}
.steppill{display:inline-flex;align-items:center;gap:0.4375rem;background:rgba(55,138,221,.14);
  border:1px solid rgba(55,138,221,.35);color:#8CC0F5;border-radius:999px;padding:0.3125rem 0.8125rem;
  font-size:0.75rem;font-weight:700;margin-bottom:1.125rem}
.steppill .flag{font-size:0.6875rem}
.goal-h{font-size:1.6875rem;font-weight:500;letter-spacing:-.01em;line-height:1.2;margin:0 0 0.5rem;color:#fff;text-align:center}
.goal-help{color:#9FB0C4;font-size:0.875rem;margin:0 0 1.625rem}
.goal-field{position:relative;width:100%;display:flex;align-items:center;gap:0.625rem;
  background:#101E33;border:1px solid #2A3C55;border-radius:12px;padding:0 0.75rem 0 1rem;transition:border-color .15s,box-shadow .15s}
.goal-field:focus-within{border-color:#378ADD;box-shadow:0 0 0 4px rgba(55,138,221,.15)}
.goal-target{color:#378ADD;font-size:1.125rem;flex:none;line-height:1}
.goal-in{flex:1;min-width:0;background:none;border:none;outline:none;color:#fff;font-size:0.9375rem;padding:0.9375rem 0}
.goal-in::placeholder{color:#6E8199}
.goal-enter{flex:none;color:#7F93AB;font-size:0.6875rem;font-weight:600;background:rgba(127,147,171,.12);
  border-radius:6px;padding:0.1875rem 0.5rem;white-space:nowrap}
.goal-chips{display:flex;flex-wrap:wrap;gap:0.5rem;justify-content:center;margin-top:1rem}
.goal-chip{background:rgba(16,30,51,.7);border:1px solid #2A3C55;color:#C4D2E4;border-radius:20px;
  padding:0.375rem 0.8125rem;font-size:0.75rem;font-weight:600;cursor:pointer}
.goal-chip:hover{border-color:#378ADD;color:#fff}
.goal-acts{display:flex;align-items:center;justify-content:space-between;width:100%;gap:1rem;margin-top:1.875rem}
.goal-cancel{background:none;border:none;color:#9FB0C4;font-size:0.875rem;font-weight:600;cursor:pointer;padding:0.5rem 0.25rem}
.goal-cancel:hover{color:#fff}
.goal-next{background:#378ADD;color:#fff;border:none;border-radius:10px;padding:0.75rem 1.375rem;font-size:0.875rem;font-weight:700;cursor:pointer;transition:background .15s,opacity .15s}
.goal-next:hover{background:#2f79c4}
.goal-next:disabled{opacity:.5;cursor:default}   /* muted (still reads as the primary) until the field has content */
/* friendly mascot + speech bubble, bottom-right (desktop). */
.goal-mascot{position:absolute;right:1.625rem;bottom:1.375rem;display:flex;flex-direction:column;align-items:center;gap:0.5rem;pointer-events:none}
.goal-bubble{position:relative;background:#0D1626;border:1px solid #2A3C55;color:#C4D2E4;border-radius:12px;
  padding:0.5rem 0.75rem;font-size:0.75rem;max-width:10.5rem;text-align:center;line-height:1.35}
.goal-bubble:after{content:"";position:absolute;left:50%;bottom:-0.375rem;transform:translateX(-50%) rotate(45deg);
  width:0.625rem;height:0.625rem;background:#0D1626;border-right:1px solid #2A3C55;border-bottom:1px solid #2A3C55}
@media (prefers-reduced-motion: no-preference){ .goal-mascot{animation:goal-float 4s ease-in-out infinite} }
@keyframes goal-float{0%,100%{transform:translateY(0)}50%{transform:translateY(-6px)}}
/* TABLET 481-1023: ease the headline. */
@media(max-width:1023px){ .goal-h{font-size:1.5rem} }
/* iPHONE ≤480: stacked, left-aligned, bottom-anchored full-width Continue (not squished). */
@media(max-width:480px){
  .goalstep{min-height:calc(100dvh - 6.875rem);justify-content:flex-start;align-items:stretch;text-align:left;
    padding:1.125rem 1rem calc(1.25rem + env(safe-area-inset-bottom))}
  .goalcol{align-items:stretch;max-width:100%;flex:1}
  .steppill{align-self:flex-start}
  .goal-h{font-size:1.25rem;text-align:left}
  .goal-help{text-align:left}
  .goal-chips{justify-content:flex-start}
  .goal-enter{display:none}
  .goal-mascot{position:static;animation:none;flex-direction:row;align-items:center;gap:0.625rem;margin:auto 0 1rem;align-self:flex-start}
  .goal-mascot svg{width:2.75rem;height:2.75rem}
  .goal-bubble{max-width:none}
  .goal-acts{flex-direction:column-reverse;align-items:stretch;gap:0.625rem;margin-top:0}
  .goal-next{width:100%;text-align:center;padding:0.9375rem}
  .goal-cancel{width:100%;text-align:center;padding:0.75rem}
}

/* breadcrumb + drill-down focus */
.crumbbar{display:flex;align-items:center;gap:0.3125rem;flex-wrap:wrap;margin:0 0 1rem}
.crumb-i{background:var(--surface2);border:1px solid var(--line);color:var(--muted);border-radius:999px;padding:0.3125rem 0.8125rem;font-weight:700;font-size:0.78125rem}
.crumb-i:hover{color:var(--txt);border-color:var(--line2);transform:translateY(-1px)}
.crumb-i.on{background:var(--accent);color:#fff;border-color:var(--accent)}
.crumb-sep{color:var(--faint)}
.iconbtn,.cardedit{background:transparent;border:none;color:var(--faint);padding:0.125rem 0.4375rem;font-size:0.8125rem;border-radius:7px;font-weight:700}
.iconbtn:hover,.cardedit:hover{background:var(--surface2);color:var(--txt)}
.focusboard{display:block}
.focuswrap{animation:pop .3s var(--spring) both;max-width:65rem}
.focushead{display:flex;gap:1rem;align-items:flex-start;background:color-mix(in srgb,var(--surface) 92%,transparent);
  border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--sh);padding:1.125rem 1.25rem;margin-bottom:1.125rem}
.fh-main{flex:1;min-width:0}
.fh-kind{font-size:0.65625rem;font-weight:800;letter-spacing:.06em;color:var(--accent2)}
.fh-title{font-size:1.3125rem;font-weight:800;letter-spacing:-.01em;margin:0.1875rem 0 0.375rem}
.fh-meta{color:var(--muted);font-size:0.84375rem;line-height:1.5}
.fh-actions{display:flex;gap:0.5rem;flex:none}
.childgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(15.25rem,1fr));gap:0.75rem}
.childgrid .tk{animation:pop .34s var(--spring) both}
.focusfoot{display:flex;gap:0.625rem;margin-top:1.125rem}

/* Focus spotlight — the do-it loop. One big card, nothing else. */
.spotwrap{display:grid;place-items:center;min-height:54dvh;padding:0.625rem}
.spot{width:min(40rem,96%);background:var(--surface);border:1px solid var(--line);border-radius:24px;
  box-shadow:var(--sh-lg);padding:2.125rem 2rem;text-align:center;animation:pop .4s var(--spring) both;
  position:relative;overflow:hidden}
.spot:before{content:"";position:absolute;top:0;left:0;right:0;height:0.3125rem;background:linear-gradient(90deg,var(--accent),var(--accent2))}
.spot-meta{display:flex;align-items:center;justify-content:center;gap:0.5rem;margin-bottom:1rem;flex-wrap:wrap}
.spot-title{font-size:1.6875rem;font-weight:800;letter-spacing:-.02em;line-height:1.25;margin:0 0 0.875rem}
.spot-reason{color:var(--accent2);font-size:0.90625rem;font-weight:600;line-height:1.5;margin:0 auto 1.625rem;max-width:80%}
.spot-art{margin:0 auto 0.875rem;max-width:14.375rem}
.spot-art svg{width:100%;height:auto;display:block;border-radius:18px;box-shadow:var(--sh)}
.spot-acts{display:flex;gap:0.75rem;justify-content:center;flex-wrap:wrap}
.spot-acts button{padding:0.8125rem 1.625rem;font-size:0.9375rem;border-radius:14px}
.spot-acts2{display:flex;gap:0.75rem;justify-content:center;align-items:center;flex-wrap:wrap;margin-top:0.875rem}
/* "Break it into steps" — a headline feature, so it's loud and red, not a subtle link. */
.breakdown{display:block;margin:1.125rem auto 0;padding:0.75rem 1.25rem;border-radius:12px;font-size:0.9375rem;font-weight:800;
  color:var(--accent);background:var(--accent-soft);border:1px solid color-mix(in srgb,var(--accent) 45%,transparent);cursor:pointer;transition:transform .12s,background .2s}
.breakdown:hover{transform:translateY(-1px);background:color-mix(in srgb,var(--accent) 22%,transparent)}
.breakdown:active{transform:translateY(0)}
.ftimer{font-variant-numeric:tabular-nums;font-weight:800;color:var(--accent2);min-width:2.625rem;font-size:0.9375rem}
/* Hero workbench action bar (in the ticket editor): mark-done + press-and-hold explode. */
.hero-acts{display:flex;gap:0.625rem;align-items:center;margin:0.375rem 0 1rem}
/* Equal weight with the break button — a SOFT green-tinted button, NOT a solid fill (a filled
   green read as "already done / selected" on load). Both actions now sit as equal-weight, equal-
   width choices; "done" only solidifies AFTER you tap it. */
.hero-acts .hero-done{flex:1;padding:0.6875rem 1rem;border-radius:11px;font-weight:800;font-size:0.875rem;cursor:pointer;
  color:var(--done);background:color-mix(in srgb,var(--done) 14%,transparent);border:1px solid color-mix(in srgb,var(--done) 45%,transparent);transition:transform .12s,background .2s}
.hero-acts .hero-done:hover{transform:translateY(-1px);background:color-mix(in srgb,var(--done) 24%,transparent)}
.hero-acts .hero-done:disabled{opacity:.6;cursor:default}
.hero-acts .hero-break{display:block;margin:0;flex:1;padding:0.6875rem 1rem;font-size:0.875rem}   /* override centered .breakdown */
.spot-foot{display:flex;align-items:center;gap:0.625rem;margin-top:1.5rem;padding-top:1.125rem;border-top:1px solid var(--line);font-size:0.78125rem;color:var(--muted)}
.spot-target{display:inline-flex;align-items:center;gap:0.5rem}
/* puzzle reward */
.puzzle{position:relative;width:18.75rem;max-width:88%;margin:1.125rem auto 0.25rem;border-radius:14px;overflow:hidden;cursor:pointer;
  border:1px solid var(--line);box-shadow:var(--sh);animation:pop .35s var(--spring) both}
.puzzle canvas{display:block;width:100%;height:auto;transition:filter .4s var(--ease)}
.pcells{position:absolute;inset:0;display:grid;grid-template-columns:repeat(6,1fr);grid-template-rows:repeat(4,1fr)}
.pcube{background:var(--surface2);border:1px solid color-mix(in srgb,var(--bg) 60%,var(--surface2));transition:opacity .5s var(--ease),transform .5s var(--spring)}
.pcube.off{opacity:0}
.pcube.reveal{animation:pieceIn .6s var(--spring) both}
@keyframes pieceIn{0%{opacity:1;transform:scale(1)}100%{opacity:0;transform:scale(1.25)}}
.pbar{position:absolute;left:0;right:0;bottom:0;display:flex;justify-content:space-between;align-items:center;
  padding:0.375rem 0.625rem;font-size:0.71875rem;font-weight:700;color:#fff;background:linear-gradient(transparent,rgba(0,0,0,.55))}
.pbar .pmore{opacity:.8}
.ggrid{display:grid;grid-template-columns:repeat(2,1fr);gap:0.75rem}
.gpic{display:flex;flex-direction:column;gap:0.3125rem;align-items:center}
.gpic img{width:100%;border-radius:10px;border:1px solid var(--line)}
.gpic span{font-size:0.75rem;color:var(--muted);font-weight:600}
.streak{display:flex;align-items:center;gap:0.625rem;justify-content:center;margin-bottom:1rem;font-size:0.8125rem;color:var(--muted);font-weight:600}
.streak .st-on{color:var(--accent)} .streak .st-sep{color:var(--faint)} .streak b{color:var(--txt)}
.spot.done .spot-big{font-size:3.5rem;color:var(--done)} .spot.done{padding:2.75rem 2rem}
.spot.done .spot-foot{justify-content:center;border:none;padding-top:0.5rem}

.maptools{display:flex;align-items:center;gap:0.5rem;margin-bottom:0.75rem;color:var(--muted);flex-wrap:wrap}
/* slim "next thing" hero atop the Map */
.maphero{display:flex;align-items:center;gap:0.625rem;padding:0.75rem 1rem;margin-bottom:0.875rem;border-radius:14px;
  background:linear-gradient(120deg,var(--cyan-soft),transparent);border:1px solid color-mix(in srgb,var(--accent2) 30%,var(--line))}
.maphero .mh-tag{font-size:0.6875rem;font-weight:800;color:var(--accent2);letter-spacing:.04em;flex:none}
.maphero .mh-title{font-weight:700;color:var(--txt);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.msum{font-size:0.8125rem;color:var(--muted);margin:-0.25rem 0 0.875rem} .msum b{color:var(--txt)}
.mbars{display:flex;align-items:flex-end;gap:0.3125rem;height:5.625rem}
.mbar{flex:1;display:flex;flex-direction:column;align-items:center;gap:0.3125rem;height:100%;justify-content:flex-end}
.mbar span{width:100%;max-width:1.375rem;background:linear-gradient(var(--accent2),var(--accent));border-radius:5px 5px 2px 2px;transition:height .5s var(--ease)}
.mbar i{font-size:0.59375rem;color:var(--faint);font-style:normal}
.link{color:var(--accent2);cursor:pointer;font-weight:700;text-decoration:none} .link:hover{text-decoration:underline}
.capchips{display:flex;flex-wrap:wrap;gap:0.4375rem;margin-top:0.625rem}
.chip{background:var(--surface2);border:1px solid var(--line);color:var(--txt);border-radius:999px;padding:0.375rem 0.75rem;font-size:0.78125rem;font-weight:600}
.chip:hover{border-color:var(--accent2);transform:translateY(-1px)}
.cmtlist{display:flex;flex-direction:column;gap:0.4375rem;max-height:11.25rem;overflow:auto;background:var(--surface2);border:1px solid var(--line);border-radius:var(--r-sm);padding:0.5625rem}
.cmt{font-size:0.8125rem;line-height:1.45} .cmt-a{font-weight:700;color:var(--accent2);margin-right:0.4375rem}

/* board / cards */
.board{display:flex;gap:1.125rem;align-items:flex-start;overflow-x:auto;padding:0.25rem 0.125rem 0.875rem;scrollbar-width:none}
.board::-webkit-scrollbar{display:none}
.col{background:color-mix(in srgb,var(--surface) 92%,transparent);border:1px solid var(--line);border-radius:var(--r);
  width:18.75rem;min-width:18.75rem;box-shadow:var(--sh);display:flex;flex-direction:column;max-height:calc(100vh - 20rem);
  animation:pop .4s var(--spring) both}
.col .ch{padding:0.875rem 0.9375rem 0.75rem;border-bottom:1px solid var(--line)}
.col .ch .row1{display:flex;align-items:center;gap:0.5625rem}
.col .ch .bdot{width:0.625rem;height:0.625rem;border-radius:3px;flex:none}
/* FB 1fa24ef5: lanes must READ differently from tasks - lane headers are small
   uppercase letter-spaced labels; task titles stay sentence-case white. */
.col .ch h3{margin:0;font-size:0.75rem;font-weight:800;flex:1;cursor:text;text-transform:uppercase;letter-spacing:.12em;color:var(--accent2,#6ACBFF)}
.count{font-size:0.6875rem;font-weight:800;color:var(--muted);background:var(--surface2);border-radius:999px;padding:0.125rem 0.5625rem}
.col .ch .resp{color:var(--faint);font-size:0.75rem;margin-top:0.375rem;line-height:1.45}
.col .cb{padding:0.75rem;display:flex;flex-direction:column;gap:0.625rem;overflow-y:auto}
.col .cf{padding:0 0.75rem 0.875rem}
.tk{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-sm);padding:0.75rem 0.8125rem;
  cursor:pointer;transition:transform .15s var(--spring),box-shadow .15s,border-color .15s;animation:pop .36s var(--spring) both}
.tk:hover{transform:translateY(-3px);box-shadow:var(--sh);border-color:var(--line2)}
.tk:active{transform:translateY(0) scale(.99)}
.tk:focus-visible{outline:none;box-shadow:var(--ring)}
.tk .top{display:flex;align-items:center;gap:0.5rem}
.badge{width:1.1875rem;height:1.1875rem;border-radius:6px;display:grid;place-items:center;font-size:0.625rem;font-weight:800;color:#fff;flex:none}
.tk .key{font-family:ui-monospace,SFMono-Regular,monospace;font-size:0.6875rem;color:var(--muted)}
.tk .title{margin-top:0.4375rem;line-height:1.35;font-weight:600}
.tk .row{margin-top:0.625rem;display:flex;gap:0.375rem;flex-wrap:wrap;align-items:center}
.pill{font-size:0.65625rem;font-weight:700;padding:0.125rem 0.5625rem;border-radius:999px;display:inline-flex;align-items:center;gap:0.3125rem}
.pill .dot{width:0.375rem;height:0.375rem}
.pill.s{background:var(--surface2);color:var(--muted)}
.pill.review{background:var(--warn-soft);color:var(--warn)}
.tk.child{margin-left:0.875rem;border-left:3px solid var(--line2)}
.tk.draftnew{border-style:dashed;color:var(--muted);text-align:center;font-weight:700;background:transparent}
.tk.draftnew:hover{color:var(--accent);border-color:var(--accent)}
.empty{color:var(--faint);font-size:0.78125rem;text-align:center;padding:1rem 0.5rem;line-height:1.5}
.thinking{display:flex;align-items:center;gap:0.5625rem;color:var(--accent2);font-size:0.78125rem;font-weight:700;padding:0.625rem 0.375rem}
.thinking .sp{width:0.9375rem;height:0.9375rem;border-radius:50%;border:2px solid var(--cyan-soft);border-top-color:var(--accent2);animation:spin .8s linear infinite}
/* ── Ferrofluid loader (ferroLoader in core.js): gooey metaballs merge/spike via #ferrogoo. ── */
.ferro-wrap{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:1.375rem;min-height:46vh;padding:1.5rem}
.ferro{position:relative;width:13.75rem;height:13.75rem;filter:url(#ferrogoo)}
.fblob{position:absolute;top:50%;left:50%;border-radius:50%;transform:translate(-50%,-50%);will-change:transform;
  background:radial-gradient(circle at 34% 28%,#cfe8ff 0%,#3b9dff 42%,#2D7CFF 64%,#0a1733 100%);
  animation:ferroMove ease-in-out infinite}
@keyframes ferroMove{
  0%,100%{transform:translate(-50%,-50%) translate(0,0) scale(.9)}
  50%{transform:translate(-50%,-50%) translate(var(--ox,0),var(--oy,0)) scale(1.1)}
}
.ferro-msg{display:flex;align-items:center;gap:0.625rem;color:var(--muted);font-size:0.84375rem;font-weight:700;letter-spacing:.02em}
/* The dedicated loader creature (big beetle + grab-arms) was RETIRED (Ken 2026-06-14 "get rid of
   this loading screen, just have the creature 10x intensity when loading"). The loader is now just
   the .ferro-msg copy; the always-on AMBIENT creature goes 10× berserk while it's up (ferro.js). */
/* HERO SUPERPOWERS (2026-07-01, docs/hero-superpowers-work-order.md): the per-class AI verb button
   (⚡ Do it for me / ✍️ Draft the words — rides the .breakdown ghost look, accent-tinted so it reads
   as "the AI moves") + the When? implementation-intention chips (quiet, non-punitive — an intention,
   never a deadline). A "you"-class card renders NO ai-verb (absence = honesty). */
.cs-actions .ai-verb{border-color:color-mix(in srgb,var(--accent,#378ADD) 55%,transparent);color:var(--accent,#378ADD)}
.cs-actions .ai-verb.loading{opacity:.7;pointer-events:none}
.cs-when{display:flex;align-items:center;gap:0.5rem;margin:0.375rem 0 0;flex-wrap:wrap}
.when-lbl{font-size:0.78125rem;color:var(--muted);font-weight:700}
.when-chip{border:1px solid var(--line,#2A3C55);background:transparent;color:var(--muted);border-radius:999px;
  padding:0.25rem 0.8125rem;font-size:0.78125rem;cursor:pointer}
.when-chip:hover{border-color:var(--accent,#378ADD);color:var(--accent,#378ADD)}
.when-chip.on{border-color:var(--accent,#378ADD);color:var(--accent,#378ADD);font-weight:700;
  background:color-mix(in srgb,var(--accent,#378ADD) 10%,transparent)}
/* PLANOS LOADER (Ken 2026-07-01 "hide him... in his stead (when loading only) a new planos themed
   loading indication"): the creature is FERRO_OFF (core.js knob) — loading now shows ONE BIG PIECE
   breaking into THREE SMALL ONES on a loop, the product's whole promise as a heartbeat. Paper chips
   (theme vars → cream-on-ink in ink, dark-theme fallbacks), fluid rem, transform/opacity only. */
.plo-load{display:flex;align-items:center;gap:0.875rem}
.plo-p{display:block;border-radius:0.5rem;background:var(--surface,#f6f0e1);border:2px solid var(--txt,#2c2a23);box-shadow:0 2px 0 rgba(0,0,0,.22)}
.plo-p.p0{width:3.25rem;height:3.25rem;animation:ploBig 1.8s ease-in-out infinite;--tilt:-4deg}
.plo-p.p1,.plo-p.p2,.plo-p.p3{width:1.375rem;height:1.375rem;animation:ploPiece 1.8s ease-in-out infinite;opacity:0}
.plo-p.p1{--tilt:-7deg}
.plo-p.p2{animation-delay:.16s;--tilt:4deg}
.plo-p.p3{animation-delay:.32s;--tilt:-3deg}
@keyframes ploBig{0%,22%{transform:rotate(var(--tilt)) scale(1);opacity:1}42%,78%{transform:rotate(var(--tilt)) scale(.42);opacity:.2}100%{transform:rotate(var(--tilt)) scale(1);opacity:1}}
@keyframes ploPiece{0%,22%{transform:rotate(var(--tilt)) translateY(0.4375rem) scale(.35);opacity:0}42%,78%{transform:rotate(var(--tilt));opacity:1}100%{transform:rotate(var(--tilt));opacity:0}}
@media (prefers-reduced-motion: reduce){ .plo-p{animation:none!important;opacity:1!important;transform:none!important} }
@media (prefers-reduced-motion: reduce){ .ferro{filter:none} .fblob{animation:none} }
.board.ferroing{display:block;overflow:visible}   /* loader centers itself; don't constrain it in the flex board */

/* KPI + reports + workspace */
.main{padding:1.5rem 1.75rem 8.125rem;min-height:100%}
.h1{font-size:1.3125rem;font-weight:800;letter-spacing:-.01em;margin:0 0 0.125rem}
.sub{color:var(--muted);font-size:0.8125rem;margin:0 0 1.125rem}
.tabs{display:inline-flex;gap:0.25rem;background:var(--surface2);border:1px solid var(--line);border-radius:999px;padding:0.25rem;margin-bottom:1.25rem}
.tabs button{background:transparent;color:var(--muted);border:none;border-radius:999px;font-weight:700;padding:0.4375rem 1rem}
.tabs button.on{background:var(--surface);color:var(--txt);box-shadow:var(--sh)}
.kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(10.625rem,1fr));gap:0.875rem;margin-bottom:1.375rem}
.kpi{background:var(--surface);border:1px solid var(--line);border-radius:var(--r);padding:1rem;box-shadow:var(--sh);display:flex;gap:0.875rem;align-items:center;animation:pop .4s var(--spring) both}
.kpi .n{font-size:1.6875rem;font-weight:800;letter-spacing:-.02em} .kpi .l{color:var(--muted);font-size:0.75rem;margin-top:0.0625rem}
.kpi .ico{width:2.625rem;height:2.625rem;border-radius:12px;display:grid;place-items:center;background:var(--cyan-soft);color:var(--accent2);flex:none}
.donut{--p:0;width:3.25rem;height:3.25rem;border-radius:50%;flex:none;background:conic-gradient(var(--done) calc(var(--p)*1%),var(--surface2) 0);display:grid;place-items:center}
.donut span{width:2.375rem;height:2.375rem;border-radius:50%;background:var(--surface);display:grid;place-items:center;font-size:0.75rem;font-weight:800}
.panel{background:var(--surface);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--sh);padding:1.125rem;margin-bottom:1rem;animation:pop .4s var(--spring) both}
.panel h4{margin:0 0 0.8125rem;font-size:0.75rem;color:var(--muted);text-transform:uppercase;letter-spacing:.05em;font-weight:800}
.barline{display:flex;align-items:center;gap:0.625rem;margin:0.625rem 0;font-size:0.8125rem}
.barline .lab{width:6rem;color:var(--muted)} .barline .track{flex:1;height:0.625rem;border-radius:99px;background:var(--surface2);overflow:hidden}
.barline .fill{height:100%;border-radius:99px;transition:width .6s var(--ease)} .barline .v{width:2.25rem;text-align:right;color:var(--muted);font-variant-numeric:tabular-nums}
.list .li{display:flex;align-items:center;gap:0.625rem;padding:0.625rem 0.125rem;border-bottom:1px solid var(--line)}
.list .li:last-child{border-bottom:none}
.chips{display:flex;gap:0.5rem;flex-wrap:wrap}

/* AI dock */
.dock{position:absolute;left:0;right:0;bottom:0;background:color-mix(in srgb,var(--surface) 86%,transparent);backdrop-filter:blur(14px);
  border-top:1px solid var(--line);padding:0.8125rem 1.625rem;display:flex;gap:0.75rem;align-items:center;box-shadow:0 -8px 30px rgba(0,0,0,.18);z-index:18}
.dock .sparkle{width:2.375rem;height:2.375rem;border-radius:11px;background:linear-gradient(135deg,var(--accent2),#5ad6ef);color:#05222a;display:grid;place-items:center;flex:none;box-shadow:0 4px 14px var(--cyan-soft)}
.dock input{flex:1}
.seg{display:flex;gap:0.5rem;flex:none}

/* drawer (review + edit) */
.scrim{position:fixed;inset:0;background:rgba(6,8,14,.55);opacity:0;pointer-events:none;transition:.2s;z-index:40;backdrop-filter:blur(2px)}
.scrim.on{opacity:1;pointer-events:auto}
.drawer{position:fixed;top:0;right:0;height:100vh;width:min(36.25rem,96vw);background:var(--surface);border-left:1px solid var(--line);
  box-shadow:var(--sh-lg);transform:translateX(100%);transition:transform .28s var(--spring);z-index:41;display:flex;flex-direction:column}
.drawer.on{transform:none}
.drawer .dh{padding:1.25rem;border-bottom:1px solid var(--line)}
.drawer .dh .t{font-size:1.0625rem;font-weight:800} .drawer .dh .d{color:var(--muted);font-size:0.8125rem;margin-top:0.1875rem}
.drawer .dc{flex:1;overflow-y:auto;padding:1.125rem 1.25rem}
.drawer .df{padding:1rem 1.25rem;border-top:1px solid var(--line);display:flex;gap:0.625rem;align-items:center}
.op{border:1px solid var(--line);border-radius:var(--r-sm);padding:0.8125rem;margin-bottom:0.6875rem;background:var(--surface);animation:pop .3s var(--spring) both}
.op.err{border-color:var(--block)} .op.rev{border-color:var(--warn)}
.op .oh{display:flex;align-items:center;gap:0.5625rem}
.op .verb{font-size:0.625rem;font-weight:800;text-transform:uppercase;letter-spacing:.04em;padding:0.1875rem 0.5625rem;border-radius:7px;background:var(--cyan-soft);color:var(--accent2)}
.op .verb.create{background:rgba(63,185,80,.16);color:var(--done)}.op .verb.update{background:rgba(59,157,255,.16);color:var(--prog)}.op .verb.link{background:rgba(163,113,247,.16);color:var(--review)}
.op .name{font-weight:700} .op .reason{color:var(--warn);font-size:0.75rem;margin-top:0.5rem}
.op .det{color:var(--muted);font-size:0.78125rem;margin-top:0.5rem;line-height:1.5;white-space:pre-wrap}
.banner{padding:0.6875rem 0.875rem;border-radius:var(--r-sm);font-size:0.8125rem;margin-bottom:0.875rem;font-weight:600}
.banner.warn{background:var(--warn-soft);color:var(--warn)} .banner.ok{background:rgba(63,185,80,.14);color:var(--done)}
.fld label{display:block;font-size:0.75rem;color:var(--muted);margin-bottom:0.375rem;font-weight:700}
.fld+.fld{margin-top:0.875rem}

/* modal / toast / console */
.toast{position:fixed;bottom:calc(6rem + env(safe-area-inset-bottom));left:50%;transform:translateX(-50%) translateY(10px);background:var(--txt);color:var(--bg);
  padding:0.6875rem 1.125rem;border-radius:12px;font-size:0.8125rem;font-weight:700;box-shadow:var(--sh-lg);opacity:0;transition:.22s var(--spring);z-index:60;pointer-events:none;max-width:80vw}
.toast.on{opacity:1;transform:translateX(-50%)}
.toast.bad{background:var(--block);color:#fff} .toast.ok{background:var(--done);color:#06270d}
/* Actionable (Undo) toast: clickable, with a button. */
.toast.undo{pointer-events:auto;display:inline-flex;align-items:center;gap:0.875rem}
.toast-undo{background:none;border:none;color:var(--accent2,#63D4FF);font-weight:800;cursor:pointer;font-size:0.8125rem;padding:0.125rem 0.25rem;text-decoration:underline}
.modal{position:fixed;inset:0;display:none;place-items:center;background:rgba(6,8,14,.55);z-index:50;backdrop-filter:blur(2px)}
.modal.on{display:grid}
.modal .box{background:var(--surface);border:1px solid var(--line);border-radius:var(--r);width:min(27.5rem,94vw);box-shadow:var(--sh-lg);animation:pop .3s var(--spring) both}
.modal .box h3{margin:0;padding:1.125rem 1.25rem;border-bottom:1px solid var(--line);font-size:0.9375rem}
.modal .box .c{padding:1.125rem 1.25rem;display:flex;flex-direction:column;gap:0.8125rem}
.modal .box .f{padding:0.9375rem 1.25rem;border-top:1px solid var(--line);display:flex;justify-content:flex-end;flex-wrap:wrap;row-gap:0.5rem;gap:0.625rem}
/* ── Debug feedback button (rapid-iteration loop; gated by S.debug, removable) ── */
/* Bottom-LEFT so it never sits on top of the right-aligned tiles/CTAs (user feedback:
   "feedback button goes over other button"). Compact + semi-transparent to stay out
   of the way; the left edge has no other fixed controls. */
/* Vertical feedback TAB pinned to the left gutter (the dark space beside the centered
   app body), text running bottom-to-top, red, capped to a fraction of viewport height,
   vertically centered. Requested: "vertical in the black space on the left … a max
   percent vertical height … vertical … red." */
/* Compact left-edge tab — slim enough it never crowds/overlaps the content cards
   (the old version was a thick bar that looked squashed against cards on mobile). */
.fbtn{position:fixed;left:0;top:50%;transform:translateY(-50%);z-index:46;
  writing-mode:vertical-rl;transform-origin:left center;
  height:max-content;max-height:34vh;padding:0.6875rem 0.25rem;
  border-radius:0 10px 10px 0;
  background:var(--block);color:#fff;font-weight:700;font-size:0.6875rem;letter-spacing:.03em;
  border:none;box-shadow:2px 4px 18px rgba(0,0,0,.35);cursor:pointer;opacity:.9;
  transition:transform .12s,opacity .2s}
.fbtn:hover{opacity:1;transform:translateY(-50%) translateX(2px)}
@media (prefers-reduced-motion: reduce){ .fbtn,.fbtn:hover{transition:none} }
.fbfile{display:inline-flex;align-items:center;gap:0.5rem;font-size:0.8125rem;color:var(--accent2);font-weight:700;cursor:pointer}
.fbfile:hover{text-decoration:underline}
/* body-double: host "sit with me" live strip + public guest overlay */
.sitlive{margin-top:0.25rem;padding:0.75rem 0.875rem;border:1px solid var(--line);border-radius:12px;background:var(--bg);text-align:center;font-weight:700;color:var(--muted);transition:color .2s,border-color .2s}
.sitlive.live{color:var(--txt);border-color:var(--cyan)}
.sitlive .big{font-size:1.375rem;display:block}
#sitLink{font-family:ui-monospace,monospace;font-size:0.75rem}
#sitGuest,#shareGuest{position:fixed;inset:0;z-index:80;display:none;place-items:start center;background:radial-gradient(120% 120% at 50% 0%,#10204a 0%,var(--bg) 60%);overflow:auto;padding:1.5rem}   /* start-center + card margin:auto = stays centered when it fits, scrolls FROM THE TOP when the shared task is taller than the viewport (no clipped/unreachable top — responsive-audit fix) */
#sitGuest.on,#shareGuest.on{display:grid}
.shg-reply{width:100%;margin:0.875rem 0;background:var(--bg);border:1px solid var(--line);border-radius:12px;padding:0.75rem 0.875rem;color:var(--txt);font:inherit;resize:vertical}
#shgDesc:empty{display:none}
.sitg-card{width:min(28.75rem,94vw);margin:auto;background:var(--surface);border:1px solid var(--line);border-radius:20px;box-shadow:var(--sh-lg);padding:1.875rem 1.625rem;text-align:center;animation:pop .4s var(--spring) both}
/* SHARED-TICKET recipient = a FULL, SPACIOUS PAGE (Ken 2026-07-07 "much larger — an entire page, plenty
   of room since they don't need the playlist; use all the real estate, easy to read"): mirror the hero
   look but big + left-aligned + generous type. */
.shg-hero{width:min(54rem,92vw)!important;max-width:54rem;padding:clamp(1.75rem,4vw,3.25rem) clamp(1.5rem,4vw,3.25rem)!important;text-align:left!important;margin:auto}
.shg-hero .hero-ctx{margin-bottom:0.5rem}
.shg-hero .hctx-crumb{font-size:1.0625rem}
.shg-hero .cs-title.td-bigt{font-size:clamp(2.125rem,4.6vw,3.125rem)!important;line-height:1.14;min-height:0}
.shg-hero .cs-purpose.shg-desc{font-size:1.1875rem;line-height:1.5;margin:0.875rem 0 0;opacity:.85}
.shg-hero .shg-replybox{margin:1.25rem 0 0}
.shg-hero .shg-reply{min-height:6.5rem;font-size:1.125rem;padding:1rem 1.125rem}
.shg-hero .shg-actions{margin:1.25rem 0 0}
.shg-hero .cs-done.big{width:100%;font-size:1.25rem;padding:1.1rem 1.25rem;border-radius:0.875rem}
/* .shg-foot / .shg-return are GONE (Ken 2026-07-10 "get rid of this. Both text and lines") — the Returns
   hint row and its rule were removed from the shared card; don't re-add. */
.shg-hero .sitg-foot{margin-top:1.5rem}
.sitg-foot.no-rule{border-top:0;padding-top:0}   /* the second hairline goes too — the button stands alone */
.shg-hero .shg-start{font-size:1.125rem;padding:0.9rem 1.25rem}
.sitg-top{font-size:0.8125rem;color:var(--muted);font-weight:700;letter-spacing:.02em}
.sitg-host{font-size:1.625rem;font-weight:900;margin-top:0.625rem}
.sitg-label{color:var(--muted);font-size:0.8125rem;margin:0.5rem 0 0.25rem}
.sitg-task{font-size:1.3125rem;font-weight:800;line-height:1.3;background:var(--bg);border:1px solid var(--line);border-radius:14px;padding:1rem}
.sitg-presence{margin:1rem 0;font-weight:700;color:var(--cyan);min-height:1.25rem}
button.big{width:100%;padding:0.9375rem;font-size:1rem;border-radius:14px}
.sitg-foot{margin-top:1.375rem;padding-top:1.125rem;border-top:1px solid var(--line);display:flex;flex-direction:column;gap:0.75rem}
.logbadge{display:none;background:var(--block);color:#fff;border-radius:999px;font-size:0.625rem;font-weight:800;padding:0 0.375rem;margin-left:0.3125rem}
.console{position:fixed;left:0;right:0;bottom:0;height:0;overflow:hidden;background:var(--surface);border-top:1px solid var(--line);transition:height .2s var(--ease);z-index:55;display:flex;flex-direction:column}
.console.on{height:42vh;box-shadow:var(--sh-lg)}
.console .ch{display:flex;align-items:center;gap:0.625rem;padding:0.625rem 1rem;border-bottom:1px solid var(--line);font-size:0.8125rem}
.console .cb{flex:1;overflow:auto;padding:0.375rem 0.625rem;font-family:ui-monospace,SFMono-Regular,monospace;font-size:0.71875rem;line-height:1.5}
.logrow{padding:0.25rem 0.375rem;border-bottom:1px solid var(--line);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.logrow.error{background:rgba(240,86,63,.09)} .logrow.warn{background:var(--warn-soft)}
.logt{color:var(--faint);margin-right:0.5rem}
.loglvl{font-weight:800;margin-right:0.5rem;text-transform:uppercase;font-size:0.625rem}
.loglvl.info{color:var(--prog)} .loglvl.error{color:var(--block)} .loglvl.warn{color:var(--warn)} .loglvl.ok{color:var(--done)}
.logdetail{white-space:pre-wrap;margin:0.375rem 0 0.125rem;background:var(--surface2);border:1px solid var(--line);border-radius:8px;padding:0.5rem;overflow-x:auto;color:var(--txt)}
/* 💰 admin costs panel (monetization P2) — rides the .console chrome; table only */
.costs-tbl{width:100%;border-collapse:collapse;font-size:0.8125rem}
.costs-tbl th{color:var(--muted);font-weight:600;text-transform:uppercase;font-size:0.65rem;letter-spacing:.04em}
.costs-tbl th,.costs-tbl td{text-align:left;padding:0.25rem 0.75rem 0.25rem 0;border-bottom:1px solid var(--line)}

/* 🏆 Accomplishments — the trophy wall (crossed-off list of everything finished) */
#scTrophies{position:fixed;inset:0;z-index:75;display:none;flex-direction:column;background:var(--bg);overflow:auto}
#scTrophies.on{display:flex}
.troph-head{display:flex;align-items:center;gap:0.75rem;padding:calc(0.875rem + env(safe-area-inset-top)) 1.375rem 0.875rem;border-bottom:1px solid var(--line);position:sticky;top:0;background:color-mix(in srgb,var(--surface) 88%,transparent);backdrop-filter:blur(14px);z-index:2}
.troph-head h1{font-size:1.3125rem;font-weight:800;margin:0}
.troph-count{font-size:0.8125rem;color:var(--muted);font-weight:700}
.troph-list{max-width:38.75rem;width:100%;margin:0 auto;padding:1.125rem 1rem calc(2.5rem + env(safe-area-inset-bottom))}
.troph-item{display:flex;align-items:flex-start;gap:0.75rem;padding:0.8125rem 0.875rem;border-radius:12px;border:1px solid var(--line);margin-bottom:0.5625rem;cursor:pointer;background:var(--surface);transition:transform .1s,border-color .2s;animation:pop .35s var(--spring) both}
.troph-item:hover{border-color:color-mix(in srgb,var(--done) 45%,var(--line));transform:translateY(-1px)}
.troph-check{width:1.5rem;height:1.5rem;border-radius:50%;background:var(--done);color:#04210f;display:grid;place-items:center;flex:none;font-weight:800;font-size:0.8125rem;box-shadow:0 2px 8px color-mix(in srgb,var(--done) 35%,transparent)}
.troph-body{flex:1;min-width:0}
.troph-title{font-weight:700;color:var(--txt);text-decoration:line-through;text-decoration-color:color-mix(in srgb,var(--muted) 55%,transparent)}
.troph-meta{font-size:0.75rem;color:var(--muted);margin-top:0.125rem}
.troph-when{font-size:0.75rem;color:var(--muted);flex:none;white-space:nowrap;margin-top:0.125rem}
.troph-empty{text-align:center;color:var(--muted);padding:4rem 1.25rem;font-size:0.9375rem}

/* confetti burst on a successful Init/apply */
.burst{position:fixed;inset:0;pointer-events:none;z-index:70;overflow:hidden}
.burst i{position:absolute;top:50%;left:50%;width:0.5625rem;height:0.875rem;border-radius:2px;opacity:0;animation:confetti .9s var(--ease) forwards}
/* Delete "explosion" pieces — wider rectangles that fly out in a ring (explodeCircle). */
.burst i.bigrect{width:1.5rem;height:0.8125rem;border-radius:3px;box-shadow:0 2px 8px rgba(0,0,0,.3)}
/* Undo: the ring flies BACK into the center (implodeCircle). */
.burst i.imp{animation:implode .6s var(--ease) forwards}
@keyframes implode{0%{opacity:0;transform:translate(var(--dx),var(--dy)) rotate(var(--rot)) scale(.6)}25%{opacity:1}100%{opacity:0;transform:translate(0,0) rotate(0) scale(1)}}

@keyframes pop{0%{opacity:0;transform:translateY(10px) scale(.94)}60%{transform:translateY(-2px) scale(1.012)}100%{opacity:1;transform:none}}
@keyframes spin{to{transform:rotate(360deg)}}
@keyframes confetti{0%{opacity:1;transform:translate(0,0) rotate(0)}100%{opacity:0;transform:translate(var(--dx),var(--dy)) rotate(var(--rot))}}
.hide{display:none!important}
@media(max-width:760px){.drawer{width:100vw}}
/* ── iPhone / mobile web (how it's shown to people) — respect the notch + home
   indicator, declutter the topbar so it stops overflowing, dock modals as a
   thumb-friendly bottom sheet. ── */
@media(max-width:640px){
  .topbar{gap:0.5rem;min-height:3.5rem;height:auto;
    padding:env(safe-area-inset-top) max(0.75rem,env(safe-area-inset-right)) 0 max(0.75rem,env(safe-area-inset-left))}
  .topbar .divider,#homeBtn,#consoleBtn,.conn{display:none}   /* brand-tap = home; logs/conn off the demo path */
  .brand{font-size:1rem}
  .brand .mark{width:1.625rem;height:1.625rem;font-size:0.8125rem}
  .crumb .pj{max-width:7.5rem}
  .main{padding:1.125rem 1rem calc(7.25rem + env(safe-area-inset-bottom))}
  .launch{padding-bottom:calc(1.5rem + env(safe-area-inset-bottom))}
  .launch h1{font-size:1.875rem;line-height:1.12}
  .launch .lead{font-size:0.875rem}
  .tiles{justify-content:center}          /* center the "Add something" tile on phones */
  .tile{width:min(21.25rem,100%)}            /* comfortable, balanced card width */
  .modal{place-items:end center}
  .modal .box{width:100vw;max-width:100vw;border-radius:18px 18px 0 0;
    padding-bottom:env(safe-area-inset-bottom);animation:sheet .28s var(--spring) both}
  button,.chip,.subtle,.tile,input,select{min-height:2.625rem}   /* comfortable tap targets */
  /* The draft board is horizontal on desktop; on a phone it STACKS VERTICALLY (feedback:
     "this is mostly a phone app") — full-width cards, page scrolls down, no sideways scroll. */
  .board{flex-direction:column;overflow-x:visible;gap:0.875rem}
  .board .col{width:100%;min-width:0;max-height:none}
  .childgrid{grid-template-columns:1fr}   /* drill-in children stack too */
}
@keyframes sheet{from{transform:translateY(40px);opacity:.6}to{transform:none;opacity:1}}
@media (prefers-reduced-motion: reduce){
  *{animation-duration:.001s!important;transition-duration:.05s!important}
}

/* ── Daily 1% nudge — a calm card on the launcher (willing, never nagging) ── */
.nudge-card{
  text-align:left; margin:0 auto 1.125rem; max-width:32.5rem;
  background:linear-gradient(180deg,var(--surface),var(--surface2));
  border:1px solid var(--line2); border-radius:var(--r-sm);
  padding:1rem 1.125rem; box-shadow:var(--sh); animation:pop .25s var(--spring);
}
.nudge-card .nudge-h{font-size:.78rem; letter-spacing:.04em; text-transform:uppercase;
  color:var(--accent2); font-weight:700; margin-bottom:0.375rem;}
.nudge-card .nudge-task{font-size:1.12rem; font-weight:700; color:var(--txt); margin:0.125rem 0;}
.nudge-card .nudge-why{font-size:.86rem; color:var(--muted); margin-bottom:0.5rem;}
.nudge-card .nudge-msg{font-size:.95rem; color:var(--txt); margin:0.5rem 0 0.75rem;}
.nudge-card .nudge-acts{display:flex; gap:0.625rem; flex-wrap:wrap;}
.nudge-card .nudge-acts button{min-height:2.5rem;}
@media (prefers-reduced-motion: reduce){ .nudge-card{animation:none;} }

/* ── Auth A2 sign-in / sign-up screen (the front door when accounts are required) ── */
#scAuth{display:none}
#scAuth.on{display:block}
/* Sign-in is a full-screen gate: hide the app chrome so a signed-out user sees ONLY
   the sign-in card (no topbar gear/Add to click "into" the app behind it). The Feedback
   tab STAYS (Ken 2026-06-13: must be reachable everywhere, incl. the sign-in screen — it
   opens a report modal, never navigates into the app behind the gate, so it's safe). */
body.auth-gate .topbar{display:none}
body.auth-gate .stage{padding-top:0}
.authwrap{min-height:88dvh; display:grid; place-items:center; padding:1.5rem}
.authcard{width:min(25rem,94vw); background:linear-gradient(180deg,var(--surface),var(--surface2));
  border:1px solid var(--line2); border-radius:var(--r); box-shadow:var(--sh-lg);
  padding:1.875rem 1.625rem; animation:pop .3s var(--spring) both}
.authcard .auth-brand{font-size:1.7rem; font-weight:900; letter-spacing:-.01em; text-align:center}
.authcard .auth-brand b{color:var(--accent)} .authcard .auth-brand em{color:var(--block); font-style:normal}
.authcard .auth-sub{text-align:center; color:var(--muted); margin:0.25rem 0 1.125rem; font-weight:600}
.authcard .fld{margin-bottom:0.8125rem}
.authcard input{width:100%}
.authcard .auth-err{color:var(--block); font-size:.86rem; min-height:1.125rem; margin:0.125rem 0 0.5rem}
.authcard #authGo{width:100%; padding:0.875rem; font-size:0.9375rem; border-radius:13px}
/* "or continue with" divider above the social buttons */
.authcard .auth-or{display:flex; align-items:center; gap:0.625rem; color:var(--muted); font-size:.78rem; margin:1rem 0 0.75rem}
.authcard .auth-or::before,.authcard .auth-or::after{content:""; flex:1; height:0.0625rem; background:var(--line2)}
/* Social sign-in buttons — provider-styled so the UX reads real. */
.oauth-btns{display:flex; flex-direction:column; gap:0.5rem}
.oauth-btn{width:100%; display:flex; align-items:center; gap:0.625rem;
  padding:0.6875rem 0.875rem; border-radius:12px; font-size:0.875rem; font-weight:700; cursor:pointer;
  background:#fff; color:#1f2328; border:1px solid #dadce0}
.oauth-btn>span:nth-child(2){flex:1; text-align:left}
.oauth-btn:hover{filter:brightness(.97)}
.oauth-btn.disabled{opacity:.5; cursor:not-allowed; filter:grayscale(.4)}
/* ICON-ONLY social buttons (Ken 2026-06-13): centered logo, no text, side by side */
.oauth-btns.icons{flex-direction:row; gap:0.625rem}
.oauth-btns.icons .oauth-btn{flex:1; width:auto; justify-content:center; gap:0; padding:0.875rem}
.oauth-btn.disabled:hover{filter:grayscale(.4)}   /* a disabled button never brightens on hover */
.oauth-btn .soon{flex:none; font-size:.62rem; font-weight:800; text-transform:uppercase; letter-spacing:.06em;
  color:#6b7280; background:#eceff3; border-radius:6px; padding:0.125rem 0.375rem}
.oauth-btn.prov-apple{background:#000; color:#fff; border-color:#000}
.oauth-btn.prov-microsoft{background:#fff; color:#1f2328}
.omark{display:inline-grid; place-items:center; width:1.25rem; height:1.25rem; font-weight:900; font-size:0.8125rem}
.gmark{border-radius:50%; background:conic-gradient(#ea4335 0 25%,#fbbc05 0 50%,#34a853 0 75%,#4285f4 0); color:#fff; font-size:0.75rem}
.amark{color:inherit; font-size:1rem}
.mmark{color:#0a7; font-size:0.9375rem}
/* SUBTLE mock marker (replaces the loud banner). Small, quiet red — present but not shouting. */
.mocknote{margin-top:0.5rem; text-align:center; font-size:.68rem; font-weight:600; letter-spacing:.02em;
  color:#e0564e; opacity:.8}
/* Mock OAuth consent screen — provider-styled stand-in for the hosted consent page. */
.oauthcard{max-width:23.75rem}
.oauthcard .oauth-top{display:flex; justify-content:center; margin-bottom:0.375rem}
.oauthcard .oauth-logo .omark{width:2.125rem; height:2.125rem; font-size:1.1875rem}
.oauthcard .oauth-title{text-align:center; font-weight:800; font-size:1.15rem}
.oauthcard .oauth-sub{text-align:center; color:var(--muted); margin:0.125rem 0 1.125rem; font-size:.92rem}
.oauthcard #oauthContinue{width:100%; padding:0.8125rem; border-radius:12px; margin-top:0.125rem}
.oauthcard .oauth-linkhint{text-align:center; color:var(--muted); font-size:.78rem; margin:0.125rem 0 0.375rem}
.oauthcard .linklike{display:block; width:100%; margin-top:0.5rem; background:none; border:none; cursor:pointer;
  color:var(--muted); font-size:.86rem; font-weight:600}
.oauthcard .linklike:hover{color:var(--text)}
.authcard .auth-toggle{text-align:center; color:var(--muted); font-size:.9rem; margin-top:0.875rem}
.authcard .auth-toggle a{color:var(--accent2); font-weight:700; cursor:pointer}
.authcard .auth-toggle a:hover{text-decoration:underline}
@media (prefers-reduced-motion: reduce){ .authcard{animation:none} }

/* ── Gamified "hold to break it down" — the button fills (color only) as you hold,
   then pops when the steps are created. Color-only progress via the --hp var. ── */
.breakdown{position:relative;overflow:hidden;touch-action:none;-webkit-user-select:none;user-select:none}
.breakdown.holding,.breakdown.loading{
  background:linear-gradient(90deg,var(--done) var(--hp,0%),var(--block) var(--hp,0%));
  border-color:transparent;color:#fff}
.breakdown.loading{animation:holdPulse .8s ease-in-out infinite}
.breakdown.holdpop{animation:pop .34s var(--spring)}
@keyframes holdPulse{0%,100%{filter:brightness(1)}50%{filter:brightness(1.28)}}
@media (prefers-reduced-motion: reduce){
  .breakdown.holding,.breakdown.loading,.breakdown.holdpop{animation:none}
}

/* ===== Agent relay — owner↔agent chat (modular/removable; see js/relay.js) ===== */
.relay-box{width:min(35rem,96vw);max-width:96vw;display:flex;flex-direction:column;
  height:min(42.5rem,86vh);padding:0;overflow:hidden}
/* MINIMIZED (Ken): collapse to a clickable bottom-right pill — agent keeps polling, thread kept.
   Backdrop off + clicks pass through so the app stays usable; the pill itself catches clicks. */
#relayModal.min{background:none;backdrop-filter:none;pointer-events:none;place-items:end end;padding:1rem}
#relayModal.min .relay-box{pointer-events:auto;width:auto;max-width:18.75rem;height:auto;cursor:pointer;animation:none}
#relayModal.min .relay-thread,#relayModal.min .relay-attach,#relayModal.min .relay-composer{display:none}
#relayModal.min .relay-head{border-bottom:none}
#relayModal.min .relay-head .ghost,#relayModal.min #relayStatus{display:none}   /* hide buttons + the "Online" caption in the pill (the dot already shows it) */
#relayModal.min .relay-head::after{content:"⤢";margin-left:0.375rem;color:var(--muted);font-weight:700}  /* maximize hint */
.relay-head{display:flex;align-items:center;gap:0.625rem;padding:0.875rem 1rem;border-bottom:1px solid var(--line)}
.relay-key{display:flex;gap:0.5rem;align-items:center;padding:0.625rem 1rem;border-bottom:1px solid var(--line)}
.relay-key input{flex:1;min-width:0}
#relayModal.min .relay-key{display:none}
.relay-id{display:flex;align-items:center;gap:0.5rem;font-size:0.9375rem}
.relay-dot{width:0.5625rem;height:0.5625rem;border-radius:50%;background:var(--muted);flex:none;box-shadow:0 0 0 3px color-mix(in srgb,var(--muted) 22%,transparent)}
.relay-dot.on{background:var(--ok,#42C978);box-shadow:0 0 0 3px color-mix(in srgb,#42C978 26%,transparent)}
.relay-thread{flex:1;overflow-y:auto;padding:1rem;display:flex;flex-direction:column;gap:0.625rem;background:color-mix(in srgb,var(--bg) 60%,transparent)}
.relay-msg{display:flex;max-width:86%}
.relay-msg .bubble{padding:0.5625rem 0.8125rem;border-radius:14px;font-size:0.875rem;line-height:1.45;white-space:normal;word-break:break-word}
.relay-msg.me{align-self:flex-end}
.relay-msg.me .bubble{background:var(--accent,#2D7CFF);color:#fff;border-bottom-right-radius:5px}
.relay-msg.agent{align-self:flex-start}
.relay-msg.agent .bubble{background:var(--surface);border:1px solid var(--line);border-bottom-left-radius:5px}
.relay-msg.status{align-self:flex-start;align-items:center;gap:0.4375rem;color:var(--muted);font-size:0.78125rem;opacity:.85}
.relay-msg.status .sp{width:0.75rem;height:0.75rem;border:2px solid var(--line);border-top-color:var(--accent2,#63D4FF);border-radius:50%;animation:spin .8s linear infinite;flex:none}
.relay-msg .bubble pre{margin:0.375rem 0 0;padding:0.5625rem 0.6875rem;background:#0b1220;border:1px solid var(--line);border-radius:9px;font-size:0.75rem;overflow-x:auto;white-space:pre}
.relay-msg.me.pending .bubble{opacity:.72}                  /* sent, not yet confirmed */
.relay-msg.typing .bubble{display:flex;align-items:center;gap:0.4375rem;padding:0.6875rem 0.8125rem}
.relay-msg .dots{display:inline-flex;gap:0.25rem}
.relay-msg .dots i{width:0.375rem;height:0.375rem;border-radius:50%;background:var(--muted);animation:relayDot 1.1s infinite ease-in-out}
.relay-msg .dots i:nth-child(2){animation-delay:.16s}
.relay-msg .dots i:nth-child(3){animation-delay:.32s}
@keyframes relayDot{0%,75%,100%{opacity:.35;transform:translateY(0)}38%{opacity:1;transform:translateY(-3px)}}
.relay-msg .cap{color:var(--muted);font-size:0.75rem;max-width:18.75rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
@media (prefers-reduced-motion: reduce){ .relay-msg .dots i{animation:none} }
.relay-attach{display:flex;align-items:center;gap:0.5rem;padding:0.4375rem 0.875rem;font-size:0.75rem;color:var(--muted);border-top:1px solid var(--line)}
.linkbtn{background:none;border:none;color:var(--accent2,#63D4FF);font-weight:700;cursor:pointer;font-size:0.75rem;padding:0;text-decoration:underline}
.relay-clip{flex:none;font-size:1rem;padding:0.5rem 0.625rem;min-height:2.625rem}
.relay-composer{display:flex;gap:0.5rem;align-items:flex-end;padding:0.75rem 0.875rem;border-top:1px solid var(--line)}
.relay-composer textarea{flex:1;resize:none;max-height:8.75rem;min-height:2.625rem;border-radius:12px;padding:0.625rem 0.75rem}
/* iMessage-style image messages: image stacked above the text caption inside the bubble. */
.relay-msg.me, .relay-msg.agent{flex-direction:column}
.relay-msg.me{align-items:flex-end}
.relay-msg.agent{align-items:flex-start}
.relay-img{max-width:min(15rem,72vw);max-height:18.75rem;border-radius:14px;object-fit:cover;display:block;border:1px solid var(--line)}
.relay-msg.me .relay-img{border-bottom-right-radius:5px}
.relay-msg.agent .relay-img{border-bottom-left-radius:5px}
.relay-img + .bubble{margin-top:0.25rem}
.relay-msg.me.pending .relay-img{opacity:.72}   /* sent, not yet confirmed */
/* Composer attachment preview (the staged image, before you hit Send). */
.relay-thumb{width:2.75rem;height:2.75rem;border-radius:8px;object-fit:cover;border:1px solid var(--line);flex:none}
.relay-x{background:none;border:none;color:var(--muted);cursor:pointer;font-size:0.8125rem;font-weight:800;line-height:1;padding:0.125rem 0.375rem}
.relay-x:hover{color:var(--block,#FF5A52)}
.relay-attach .linkbtn{margin-left:auto}
/* Click-to-zoom: tappable images + the isolated full-screen preview overlay. The overlay is a
   fixed top layer (z above modals) so opening it NEVER affects the layout of the page behind. */
.zoomable{cursor:zoom-in}
.imglb{position:fixed;inset:0;z-index:90;display:flex;align-items:center;justify-content:center;
  padding:1.5rem;background:rgba(4,7,14,.86);backdrop-filter:blur(4px);cursor:zoom-out}
.imglb[hidden]{display:none}
.imglb img{max-width:96vw;max-height:92vh;border-radius:12px;box-shadow:0 20px 60px rgba(0,0,0,.55)}
.zoomable{cursor:zoom-in}   /* any clickable image → opens the full-size #imgLightbox overlay */
/* Classic feedback form: small clickable preview of the attached image. */
.fb-thumb{max-width:7.5rem;max-height:7.5rem;border-radius:10px;border:1px solid var(--line);object-fit:cover;display:block}
@media(max-width:640px){ .relay-box{height:92vh;border-radius:18px 18px 0 0} .relay-msg{max-width:92%} }
@media (prefers-reduced-motion: reduce){ .relay-msg.status .sp{animation:none} }


/* Adaptive intake gate (wizard Details step) */
.intakeq{font-size:1.25rem;font-weight:600;margin:0.375rem 0 0.75rem;color:var(--ink)}
.intakeok{margin:0 0 0.625rem;color:var(--good,#42C978)}

/* FB d5f2cf3c: drill-in is an icon button like the other card icons (chips removed). */
.carddrill{background:transparent;border:none;color:var(--faint);padding:0.125rem 0.4375rem;font-size:0.8125rem;border-radius:7px;font-weight:700}
.carddrill:hover{background:var(--surface2);color:var(--txt)}

/* ---- Hero-first draft lane card (wizard step 3; Ken concept 4, 2026-06-10) ---- */
.col.hero .ch h3{text-transform:none;letter-spacing:0;font-size:1rem;color:var(--txt);font-weight:800}
.curstep{background:color-mix(in srgb,var(--accent) 12%,var(--surface));border:1px solid color-mix(in srgb,var(--accent) 32%,transparent);border-radius:var(--r-sm);padding:0.8125rem}
.cs-label{font-size:0.65625rem;font-weight:800;letter-spacing:.12em;color:var(--accent2)}
.cs-row{display:flex;align-items:center;gap:0.6875rem;margin-top:0.5625rem;cursor:pointer}
.stepnum{width:1.625rem;height:1.625rem;border-radius:50%;flex:none;display:flex;align-items:center;justify-content:center;font-weight:800;font-size:0.8125rem;background:var(--accent);color:var(--accent-ink)}
.stepnum.dim{background:var(--surface2);color:var(--muted);border:1px solid var(--line2)}
.stepnum.donechk{background:transparent;border:1px solid var(--line2);color:var(--good,#42C978);cursor:pointer}
.cs-title{font-weight:800;font-size:1rem;line-height:1.32}
/* DONE STEP KEEPS THE OPEN-CARD LAYOUT, just struck (Ken 2026-06-15: "Keep it like second image
   But cross out name like left side" — the old Undo-only morph + dim are RETIRED). The green Done
   button toggles (tap a done step to undo); the title carries the strikethrough. */
.cs-title.struck{text-decoration:line-through;text-decoration-color:#ff5a4d;text-decoration-thickness:2.5px;color:var(--muted)}
/* ===== GUNSHOT DONE (Ken 2026-06-15 "react like a gun shot... extremely satisfying, quick. Cross
   out the item on the left AND right. Release dopamine when it hits."). The Hero "✓ Done" button
   commits the step; hitting it fires gunshot()+spark() and slashes a strikethrough across BOTH the
   playlist row (left) and the hero card (right), with a recoil kick + a muzzle flash. ===== */
/* ONE ROW, ALWAYS (Ken 2026-07-01 ×2 "I want 'do it for me' moved here" — with wrap enabled the
   verb kept dropping below whenever the row ran tight): the action buttons share ONE row, nowrap,
   equal flex, shrinking together instead of wrapping. ≤480 stacks to a column (media below). */
/* one row while it FITS; wrap only when all space is taken (Ken 2026-07-03 cut-off card —
   same philosophy as his playlist rule: never distort unless space is truly gone) */
.cs-actions{display:flex;align-items:stretch;justify-content:flex-start;flex-wrap:wrap;gap:0.75rem;margin-top:1.25rem}
/* Done + Breakdown carry EQUAL weight — each is exactly HALF the row, 50/50 (Ken 2026-06-15:
   "I want done and break it down to carry same wight... exactly the same aligned 50 50"). Same
   size, padding, radius, font, height; distinct fills keep the meaning (green=finish, blue=split).
   When only one is shown (Breaking-it-down… / Undo) it just fills its half-or-more naturally. */
.cs-actions>.cs-done,.cs-actions>.hero-break,.cs-actions>.ai-verb{flex:1 1 0;min-width:0;white-space:nowrap;margin:0;padding:0.8125rem 1.375rem;
  border-radius:11px;font-size:0.9375rem;font-weight:700;display:inline-flex;align-items:center;justify-content:center;gap:0.5rem;text-align:center}
/* MARK DONE = filled green primary, ~15% larger so it DOMINATES (Ken refinement 2026-06-30). BREAK =
   bordered ghost, visually subordinate. */
.cs-actions>.cs-done:not(.is-undo){background:var(--done,#3E6B3A);color:#fff;border:1px solid transparent;box-shadow:none;
  font-size:1.0625rem;padding:1rem 1.875rem}
.cs-actions>.cs-done:not(.is-undo):hover{filter:brightness(1.06)}
.cs-actions>.hero-break{background:transparent;color:var(--txt);border:1px solid var(--line);box-shadow:none}
/* the AI verb (⚡ Do it for me / ✍️ Draft the words) sits IN the action row, right of Break smaller
   (Ken 2026-07-01 "I want this moved here" — it was rendering as a bare text link wrapped below,
   because only .hero-break got the button treatment). Bordered ghost like Break, accent-tinted. */
.cs-actions>.ai-verb{background:transparent;color:var(--accent,#378ADD);border:1px solid color-mix(in srgb,var(--accent,#378ADD) 55%,transparent);box-shadow:none}
.cs-actions>.hero-break:hover{background:color-mix(in srgb,var(--txt) 5%,transparent);border-color:var(--line2,var(--accent))}
/* line icons (Ken round-2: no emoji) */
.hic{width:1rem;height:1rem;flex:none;display:inline-block;vertical-align:-3px}
.cs-actions .hic{width:1.125rem;height:1.125rem;vertical-align:-4px}
.ha-pill .hic{width:0.8125rem;height:0.8125rem;vertical-align:-2px}
.cs-done{background:#2FBF71;color:#fff;border:none;letter-spacing:.01em;cursor:pointer}
.cs-done:hover{background:#27a862}
.cs-done:active{transform:translateY(1px)}
/* FLIP TO UNDO when the step is done (Ken 2026-06-15 "When you click done it should flip and say
   undo"): same 50/50 slot, but the green fill drops to a neutral outline so it reads as "undo". */
.cs-done.is-undo{background:transparent;color:var(--text);border:1px solid var(--line2);box-shadow:none}
.cs-done.is-undo:hover{background:transparent;border-color:var(--accent);color:var(--accent2)}
/* Breakdown DISABLED on a done step (Ken 2026-06-15 "If you select done on a ticket breakdown should
   be disabled") — dimmed, no pointer; undo the step to re-enable. */
.breakdown.hero-break.is-off{cursor:default;pointer-events:none}   /* done: non-interactive but NOT dimmed (Ken 2026-06-17) — the red cross is the only signal */
/* DONE = LOCKED (Ken 2026-06-15 "Disable going into the ticket when its set to done. Also disable
   that chat"): a done step can't be drilled into, and its ask/change box is disabled — undo first. */
.cs-row.no-drill{cursor:default}
.cs-row.no-drill::after{display:none}                 /* kill the › "open" hover hint */
.cs-clar.is-off{pointer-events:none}   /* done: non-interactive, not dimmed (Ken 2026-06-17) */
/* ASK-ABOUT-STEP (Ken 2026-06-15): per-step tutor, now JUST an always-visible box (no reveal
   button — "skip the middle man"). READ-ONLY. Sits below the actions as a quiet helper. */
.cs-clar{margin-top:1rem}
.cs-clar-row{display:flex;gap:0.5rem}
.cs-clar-row input,.cs-clar-row textarea{flex:1;background:var(--surface2,#0f1d30);color:var(--text);border:1px solid var(--line2);
  border-radius:10px;padding:0.6875rem 0.875rem;font-size:0.875rem;outline:none}
.cs-clar-row input:focus,.cs-clar-row textarea:focus{border-color:var(--accent)}
/* CONVERSATION thread (Ken 2026-06-20 "a conversation back and forth, not just one question"): the
   per-step Q&A is now a running back-and-forth — user turns right, answers left, latest in view. */
.cs-clar-thread{display:none;flex-direction:column;gap:0.5rem;margin-top:0.6875rem;max-height:15rem;overflow-y:auto}
.cs-clar-thread.on{display:flex}
/* MINIMIZE conversations when idle (Ken 2026-07-10 "when you are not actively talking I want the conversation
   minimized so its hidden"): a thread with messages shows ONLY while you're IN the chat — .chat-live is set by
   wireChatLive() on input-focus / hover of the container. Applies to EVERY chat surface (plan chat + per-step). */
.plan-chat:not(.chat-live) .cs-clar-thread.on,.cs-clar:not(.chat-live) .cs-clar-thread.on{display:none}
/* Clear-conversation control — sticky at the top of any thread, on every chat surface. */
.chat-clear-row{position:sticky;top:0;z-index:1;display:flex;justify-content:flex-end;margin:-0.2rem 0 0.15rem}
.chat-clear{font:inherit;font-size:0.72rem;letter-spacing:.03em;text-transform:uppercase;font-weight:700;background:none;border:none;color:var(--muted);opacity:.7;cursor:pointer;padding:0.1rem 0.35rem;border-radius:6px}
.chat-clear:hover{opacity:1;color:var(--bad,#b53b2d);background:color-mix(in srgb,var(--bad,#b53b2d) 10%,transparent)}
.cc-turn{font-size:0.90625rem;line-height:1.5;white-space:pre-wrap;padding:0.625rem 0.8125rem;border-radius:12px;max-width:92%}
.cc-q{align-self:flex-end;background:rgba(55,138,221,.16);border:1px solid var(--line2);color:var(--text);border-bottom-right-radius:4px}
.cc-a{align-self:flex-start;background:rgba(55,138,221,.07);border:1px solid var(--line2);color:var(--text);border-bottom-left-radius:4px}
.cc-think{opacity:.72;font-style:italic;display:inline-flex;align-items:center;gap:.5rem}
/* INLINE LOADING DOTS (Ken 2026-07-07): the modest in-bubble spinner that replaces the creature during
   inline step/plan chat waits — three dots bouncing in sequence. */
.cc-dots{display:inline-flex;gap:.24rem;flex:0 0 auto}
.cc-dots i{width:.4rem;height:.4rem;border-radius:50%;background:currentColor;opacity:.35;animation:ccDot 1s infinite ease-in-out}
.cc-dots i:nth-child(2){animation-delay:.16s}
.cc-dots i:nth-child(3){animation-delay:.32s}
@keyframes ccDot{0%,80%,100%{opacity:.3;transform:translateY(0)}40%{opacity:1;transform:translateY(-.2rem)}}
@media(prefers-reduced-motion:reduce){.cc-dots i{animation:none;opacity:.55}}
/* MULTIPLE-CHOICE option BUTTONS (Ken 2026-07-05 "make them look like buttons, obvious, draw attention"):
   SOLID filled accent pills with cream text + a lift shadow — unmistakably tappable, and they POP in with
   a staggered spring so the eye goes straight to them. (Was a faint tinted chip that washed out on cream.) */
.cc-opts{display:flex;flex-wrap:wrap;gap:0.5rem;align-self:flex-start;margin:0.25rem 0 0.375rem}
/* Inline break-it-down gate (live plan) — the multiple-choice interview under the task (Ken 2026-07-07) */
.brk-gate{display:flex;flex-direction:column;gap:0.4rem;align-items:flex-start;width:100%;margin:0.5rem 0 0.25rem}
.brk-q{font-weight:700;font-size:1rem;color:var(--txt);line-height:1.3;text-align:left}
.brk-q.brk-think{color:var(--muted);font-weight:600}
.brk-row{display:flex;gap:0.5rem;align-items:center;width:100%;flex-wrap:wrap;margin-top:0.15rem}
.brk-in{flex:1;min-width:9rem;font:inherit;font-size:0.95rem;padding:0.55rem 0.7rem;border-radius:var(--r-xs);border:1px solid var(--line);background:var(--surface);color:var(--txt)}
.brk-skip{white-space:nowrap}
.cc-opt,.iq-opt{font:inherit;font-size:1rem;font-weight:800;cursor:pointer;letter-spacing:.01em;
  padding:0.6875rem 1.25rem;border-radius:0.875rem;border:none;
  background:var(--accent,#2D7CFF);color:var(--accent-ink,#fff);
  box-shadow:0 0.3125rem 0.75rem color-mix(in srgb,var(--accent,#2D7CFF) 42%,transparent), inset 0 1px 0 rgba(255,255,255,.18);
  transition:transform .12s var(--spring),box-shadow .16s,filter .16s;
  animation:ccOptPop .32s var(--spring) both}
.cc-opt:hover,.iq-opt:hover{filter:brightness(1.08);transform:translateY(-2px);
  box-shadow:0 0.5rem 1.125rem color-mix(in srgb,var(--accent,#2D7CFF) 55%,transparent), inset 0 1px 0 rgba(255,255,255,.22)}
.cc-opt:active,.iq-opt:active{transform:translateY(0) scale(.96)}
/* staggered pop-in + a gentle attention nudge on the newest set */
@keyframes ccOptPop{from{opacity:0;transform:translateY(0.375rem) scale(.92)}to{opacity:1;transform:none}}
.cc-opts .cc-opt:nth-child(2),.iq-opts .iq-opt:nth-child(2){animation-delay:.05s}
.cc-opts .cc-opt:nth-child(3),.iq-opts .iq-opt:nth-child(3){animation-delay:.1s}
.cc-opts .cc-opt:nth-child(4),.iq-opts .iq-opt:nth-child(4){animation-delay:.15s}
@media (prefers-reduced-motion:reduce){.cc-opt,.iq-opt{animation:none}}
/* intake question options — a roomier grid above the free-text box */
/* The ↵ enter row sits DIRECTLY under the question box — and under the choices when there are choices
   (Ken 2026-07-10: his wife couldn't find the way forward; Continue used to be pinned a screen away at
   the bottom). Same shape as the home composer's .lgoal-foot, so the two intake surfaces read alike. */
.iq-foot{display:flex;align-items:center;gap:0.625rem;margin-top:0.25rem}
.iq-foot .lgoal-btn{flex:0 0 auto;min-width:9rem;max-width:60%}   /* the composer's .lgoal-btn is flex:1 — unpinned here it grew off the right edge */
.iq-foot .lgoal-btn:disabled{cursor:default}
.iq-opts{display:flex;flex-wrap:wrap;gap:0.625rem;margin:0.375rem 0 1rem}
.iq-opts-below{margin:0.5rem 0 0.75rem}   /* options sit BELOW the prompt box (Ken 2026-07-07) — hug the box */
/* INTAKE FILLS THE SCREEN (Ken 2026-07-08 "take advantage of all the space — this looks unpolished"):
   the question box + options ride a full-height flex column, vertically CENTERED, with the Back/Continue
   rail dropped to the bottom — the step reads intentional instead of a top-crammed void. Fluid dvh. */
.iq-screen{display:flex;flex-direction:column}
.iq-main{flex:1;display:flex;flex-direction:column;justify-content:center;gap:0.75rem}
/* Fill the height on phone/tablet ONLY (where the void showed) — desktop keeps its natural
   height so the wizard's 1.2× scale can't push the intake into a scroll. */
@media (max-width:1023px){ .iq-screen{min-height:min(84dvh,60rem)} }
/* "Other thoughts — tell me" (Ken 2026-07-07): a DASHED ghost chip among the option pills so it's obvious
   you can skip the presets and type your own; a tap just focuses the box. */
.iq-own,.cc-own{background:transparent!important;color:var(--muted,#5d564a)!important;border:1.5px dashed var(--line2,#cdbfa2)!important;box-shadow:none!important;font-weight:700}
.iq-own:hover,.cc-own:hover{border-color:var(--accent,#244a85)!important;color:var(--txt,#2c2a23)!important;transform:none!important;filter:none!important}
/* PLAN KEY chip beside the plan title — the stable unique identifier you reference in the operator
   scripts / API (Ken 2026-07-09 "expose the identifier on the UI for easy reference"). */
.plan-key{display:inline-block;margin-left:0.5rem;padding:0.05rem 0.4rem;border:1px solid var(--line2,#cdbfa2);border-radius:0.4rem;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:0.62em;font-weight:700;letter-spacing:.04em;color:var(--muted,#5d564a);vertical-align:middle;opacity:.8;cursor:default}
/* MANUAL START (Ken 2026-07-08 two-door): the "Start empty" secondary door + the inline hero-title input
   (type your task right on the card, no drawer). */
.lgoal-empty{background:transparent;border:1.5px solid var(--line2,#cdbfa2);color:var(--muted,#5d564a);border-radius:0.75rem;padding:0.5rem 0.95rem;font-weight:700;font-size:0.95rem;cursor:pointer}
.lgoal-empty:hover{border-color:var(--accent,#244a85);color:var(--txt,#2c2a23)}
.lgoal-empty[hidden]{display:none}
/* From-scratch API scripts — a subtle launcher-bottom link (Ken 2026-07-10, per-plan version lives on the plan footer). */
.launch-scripts{display:flex;justify-content:center;padding:0.5rem 0 0.75rem}
.lscripts-btn{font:inherit;font-size:0.8rem;background:none;border:none;color:var(--muted,#9FB0C4);opacity:.6;cursor:pointer;letter-spacing:.02em}
.lscripts-btn:hover{opacity:1;color:var(--accent,#244a85)}
.manual-title-in{width:100%;box-sizing:border-box;background:transparent;border:none;border-bottom:0.125rem dashed var(--line2,#cdbfa2);outline:none;font:inherit;color:inherit;padding:0.1rem 0}
.manual-title-in:focus{border-bottom-color:var(--accent,#244a85)}
.manual-title-in::placeholder{opacity:.55}
.iq-opt{font-size:1.0625rem;padding:0.8125rem 1.375rem}
/* GLOBAL PLAN CHAT (Ken 2026-07-05): the box above the playlist — whole-plan critique, propose-first. */
.plan-chat{margin:0 0 0.9rem;padding:0.75rem 0.9rem;background:var(--surface);border:1px solid var(--line);border-radius:var(--r-sm)}
.plan-chat .cs-clar-thread{max-height:19rem;margin-top:0}
.plan-chat .cs-clar-thread.on{margin-bottom:0.6rem}
/* PROPOSAL CARD (the "cursor plan"): exactly what would change; applied only on ✓. */
.cc-plan{align-self:stretch;max-width:100%;background:var(--surface2);border:1px dashed var(--line2);border-radius:12px;white-space:normal}
.cc-plan .ccp-title{font-weight:700;margin-bottom:0.375rem}
.cc-plan ul{margin:0 0 0.6rem;padding-left:1.1rem}
.cc-plan li{margin:0.15rem 0}
.cc-plan .ccp-btns{display:flex;gap:0.5rem;flex-wrap:wrap}
.cc-plan .ccp-hint{margin-top:0.4rem;font-size:0.78125rem;color:var(--muted)}
.cc-plan.expired{opacity:.55}
/* AUTO PURPOSE line on the hero (Ken 2026-06-20 "each ticket needs a descritpion of what its purpose
   is. These should be auto generated"): a quiet read-only "what this is for" caption under the title. */
/* DESCRIPTION = normal readable secondary text (work order Concept A 2026-06-30: not faint italic). */
.cs-purpose{display:none;margin-top:0.4375rem;font-size:0.9375rem;line-height:1.6;color:var(--muted);font-style:normal}
.cs-purpose.on{display:block}
/* HISTORY BAR near the chat (Ken 2026-06-20 "redo and undo button near chat... version number, think
   helm history"): undo/redo walk the plan's versions; the vN chip shows the current version. */
.cs-hist{display:flex;align-items:center;gap:0.5rem;margin-top:0.5625rem}
.cc-hbtn{font-size:0.8125rem;padding:0.25rem 0.625rem;border-radius:8px}
.cc-hbtn[disabled]{display:none}   /* hide Undo/Redo until there's history to act on (Ken refinement: reduce noise) */
/* v2 sits NEXT TO Undo/Redo now (Ken 2026-06-30: version + undo are related) — no auto-margin. */
.cc-ver{display:inline-flex;align-items:center;gap:0.3125rem;font-size:0.75rem;font-weight:700;letter-spacing:.04em;color:var(--muted);
  border:1px solid var(--line2);border-radius:999px;padding:0.125rem 0.5625rem}
.cc-ver .hic{width:0.875rem;height:0.875rem}
/* FRESH = a step just injected by a Breakdown; glows until looked at (Ken 2026-06-15). Pulses a
   couple times, then settles to a highlighted border+tint that clears the moment it's selected. */
.tkt-row.fresh{background:rgba(55,138,221,.13);box-shadow:inset 0 0 0 1px rgba(55,138,221,.55);
  border-radius:10px;animation:freshPulse 1.4s ease-in-out 2}
.tkt-row.fresh .uptitle{color:var(--text)}
@keyframes freshPulse{0%,100%{box-shadow:inset 0 0 0 1px rgba(55,138,221,.55)}
  50%{box-shadow:inset 0 0 0 1px rgba(55,138,221,.95),0 0 14px rgba(55,138,221,.4)}}
@media (prefers-reduced-motion: reduce){.tkt-row.fresh{animation:none}}
/* .uprow.shot = the gunshot cross-off plays on a PLAIN playlist row too (Ken 2026-06-21 "instantly
   switch as priority to next ticket. Do that [cross-off] still"): Done now swaps the hero instantly,
   so the satisfying slash fires on the persisting, now-struck playlist row after the swap. */
.cur-sel.shot,.tkt-cur.shot,.uprow.shot{position:relative;animation:gun-recoil .34s cubic-bezier(.2,.9,.25,1.15)}
@keyframes gun-recoil{0%{transform:none}12%{transform:translateX(8px) scale(1.045)}28%{transform:translateX(-3px) scale(.99)}100%{transform:none}}
.cur-sel.shot .uptitle,.tkt-cur.shot .cs-title,.uprow.shot .uptitle{position:relative}
.cur-sel.shot .uptitle::after,.tkt-cur.shot .cs-title::after,.uprow.shot .uptitle::after{content:"";position:absolute;left:-3%;top:52%;height:0.25rem;width:106%;
  background:linear-gradient(90deg,#ff5a4d,#ff8a7a);border-radius:3px;box-shadow:0 0 9px #ff5a4d;
  transform:scaleX(0);transform-origin:left;animation:gun-slash .14s .02s ease-out forwards}
@keyframes gun-slash{to{transform:scaleX(1)}}
/* SYNC the detail / Break-it-down / ask cross-outs with the title slash (Ken 2026-06-17 "I want
   everything crossed at the same time... in sync with top title cross") — they draw across DURING
   .shot, same .14s timing as .cs-title, THEN settle into the static .is-done strikes after commit. */
.tkt-cur.shot .jt-row:not(.col),.tkt-cur.shot #dBreak,.tkt-cur.shot .cs-clar{position:relative}
.tkt-cur.shot .jt-row:not(.col)::after,
.tkt-cur.shot #dBreak::after,
.tkt-cur.shot .cs-clar::after{content:"";position:absolute;left:1%;right:1%;top:50%;height:0.15625rem;
  background:#ff5a4d;border-radius:2px;box-shadow:0 0 6px rgba(255,90,77,.6);pointer-events:none;z-index:3;
  transform:translateY(-50%) scaleX(0);transform-origin:left;animation:gun-slash-row .14s .02s ease-out forwards}
@keyframes gun-slash-row{to{transform:translateY(-50%) scaleX(1)}}
.shot::before{content:"";position:absolute;inset:-0.375rem;border-radius:14px;pointer-events:none;opacity:0;
  background:radial-gradient(circle at 78% 50%,rgba(255,236,170,.95),rgba(255,120,90,.3) 40%,transparent 64%);
  animation:gun-flash .24s ease-out}
@keyframes gun-flash{0%{opacity:.95}100%{opacity:0}}
@media (prefers-reduced-motion:reduce){
  .cur-sel.shot,.tkt-cur.shot{animation:none}
  .shot::before{display:none}
  .cur-sel.shot .uptitle::after,.tkt-cur.shot .cs-title::after,.uprow.shot .uptitle::after{animation:none;transform:scaleX(1)}   /* still cross out, no motion */
  .tkt-cur.shot .jt-row:not(.col)::after,.tkt-cur.shot #dBreak::after,.tkt-cur.shot .cs-clar::after{animation:none;transform:translateY(-50%) scaleX(1)}
}
.cs-acts{display:flex;gap:0.5rem;margin-top:0.75rem}
/* Mark-done is NOT a filled/selected button (a solid blue read as "already done"). Both actions
   are equal-weight, equal-width: "done" is a soft green-tinted outline, "break" stays a soft
   outline. "Done" only solidifies AFTER you tap it. (Ken) */
.cs-acts .csdone,.cs-acts .csbreak{flex:1;padding:0.5625rem 0.875rem;border-radius:10px;font-size:0.8125rem;font-weight:800;cursor:pointer}
.cs-acts .csdone{color:var(--done);background:color-mix(in srgb,var(--done) 14%,transparent);
  border:1px solid color-mix(in srgb,var(--done) 45%,transparent);transition:transform .12s,background .2s}
.cs-acts .csdone:hover{transform:translateY(-1px);background:color-mix(in srgb,var(--done) 24%,transparent)}
.upnext-label{font-size:0.65625rem;font-weight:800;letter-spacing:.12em;color:var(--muted);margin:0.875rem 0.125rem 0.25rem;padding-top:0.75rem;border-top:1px solid var(--line)}
/* INLINE FLOW, NOT COLUMNS (Ken 2026-07-01 "Never indent unless all space is taken"): the row is
   block flow with the number + title INLINE, so a long title WRAPS TO THE ROW'S LEFT EDGE and uses
   the full width — no hanging indent under the number (the old flex columns wrapped the title
   inside its own narrow box). The › chevron moves to an absolute right slot. */
.uprow{display:block;position:relative;padding:0.5625rem 1.375rem 0.5625rem 0;border-radius:var(--r-sm);cursor:pointer}
.uprow:hover{background:var(--surface2)}
.uprow .uptitle{display:inline;font-weight:600;font-size:0.84375rem;line-height:1.3}
.uprow .upord{display:none}  /* do-order number RETIRED (Ken 2026-07-03 "I do not want the list items indented!" — the number column made line 1 start ~3em in while wrapped lines sat flush; step rows are title-only per the 2026-06-16 badge-free canon) */
.uprow .uptitle.struck{text-decoration:line-through;text-decoration-color:#ff5a4d;text-decoration-thickness:2.5px;color:var(--muted)}
.uprow+.uprow{border-top:1px solid color-mix(in srgb,var(--line) 55%,transparent)}
.herofoot{display:flex;align-items:center;gap:0.125rem;border-top:1px solid var(--line);padding-top:0.625rem!important;margin-top:0.125rem}
.linkbtn{background:transparent;border:none;color:var(--accent2);font-weight:700;font-size:0.8125rem;padding:0.375rem 0.375rem;flex:1;border-radius:var(--r-sm)}
.linkbtn:hover{background:var(--surface2)}
.linkbtn[disabled]{color:var(--muted)}
.vd{width:0.0625rem;align-self:stretch;background:var(--line);flex:none}
.iqcount{margin:0.5rem 0.125rem 0;font-size:0.75rem;color:var(--faint)}

/* ---- Phase rail (step 3 map view; inspiration mock 2026-06-10) ---- */
.mapline{margin:-0.25rem 0 0.75rem}
.phaserail{display:flex;align-items:center;gap:0;flex-wrap:wrap;margin:0 0 0.875rem}
.phaserail[hidden]{display:none}
.pr-chip{display:inline-flex;align-items:center;gap:0.4375rem;background:var(--surface);border:1px solid var(--line);border-radius:999px;color:var(--txt);font-weight:700;font-size:0.78125rem;padding:0.4375rem 0.8125rem}
.pr-chip:hover{border-color:var(--line2);background:var(--surface2)}
.pr-dot{width:0.5625rem;height:0.5625rem;border-radius:3px;flex:none}
.pr-link{width:1.625rem;height:0;border-top:2px dotted var(--line2);flex:none;margin:0 0.125rem}

/* ---- Generation skeleton (the 40s wall, fixed 2026-06-11) ---- */
.pr-chip.ghost{width:6.875rem;height:1.875rem;background:var(--surface2);border-color:transparent;animation:skelpulse 1.6s ease-in-out infinite}
.skelboard .ghostcol{background:color-mix(in srgb,var(--surface) 92%,transparent);border:1px solid var(--line);border-radius:var(--r);padding:1rem;display:flex;flex-direction:column;gap:0.75rem;min-height:13.75rem;animation:skelpulse 1.6s ease-in-out infinite}
.ghostbar{height:0.875rem;border-radius:7px;background:var(--surface2)}
.ghostbar.w60{width:60%}.ghostbar.w40{width:40%}
.ghostbox{height:5.625rem;border-radius:var(--r-sm);background:color-mix(in srgb,var(--accent) 8%,var(--surface2))}
@keyframes skelpulse{0%,100%{opacity:.55}50%{opacity:1}}
@media (prefers-reduced-motion: reduce){.pr-chip.ghost,.skelboard .ghostcol{animation:none}}

/* ---- Human review drawer (create-only plans; 2026-06-11) ---- */
.dr-phases{display:flex;gap:0.5rem;flex-wrap:wrap;margin:0.25rem 0 0.875rem}
.dr-lane{font-size:0.65625rem;font-weight:800;letter-spacing:.12em;text-transform:uppercase;color:var(--muted);margin:0.875rem 0.125rem 0.375rem}
.dr-step{display:flex;align-items:center;gap:0.625rem;padding:0.5rem 0.25rem;font-weight:600;font-size:0.84375rem;line-height:1.35}
.dr-step+.dr-step{border-top:1px solid color-mix(in srgb,var(--line) 55%,transparent)}

/* ---- Lane overflow (the amputated 4th lane; 2026-06-11): scroll, no edge fade (Ken) ---- */
.board{overflow-x:auto;scroll-snap-type:x proximity;padding-bottom:0.625rem}
.board .col{scroll-snap-align:start}
.board::-webkit-scrollbar{height:0.5rem}
.board::-webkit-scrollbar-thumb{background:var(--line2);border-radius:4px}
.iqeyebrow{font-size:0.6875rem;font-weight:800;letter-spacing:.12em;text-transform:uppercase;color:var(--muted);margin-bottom:0.5rem}
.uprow::after{content:"›";position:absolute;right:0.375rem;top:50%;transform:translateY(-50%);color:var(--faint);font-weight:800;opacity:0;transition:opacity .12s}
.uprow:hover::after{opacity:1}
.cs-row::after{content:"›";color:var(--faint);font-weight:800;opacity:0;transition:opacity .12s;margin-left:auto}
.cs-row:hover::after{opacity:1}
.planrow .del.armed{color:#fff;background:var(--block,#FF5A52);border-radius:8px;padding:0.125rem 0.5rem;font-size:0.6875rem;font-weight:800}

/* ---- Fuel bar (vertical daily-credit tank; Ken 2026-06-11) ---- */
#fuelBar{--fuel-ink:var(--accent);position:fixed;top:4rem;bottom:0.875rem;z-index:60;border-radius:999px;
  background:color-mix(in srgb,var(--surface2) 70%,transparent);overflow:hidden;cursor:pointer;transition:width .2s;
  box-shadow:inset 0 0 0 1px rgba(0,0,0,.18)}
#fuelBar:hover{width:1.625rem!important}
#fuelBar .fuel-fill{position:absolute;bottom:0;left:0;right:0;height:0;border-radius:0 0 999px 999px;
  transition:height .6s var(--spring),background .3s;overflow:visible}
/* LIQUID INK sloshing surface (Ken 2026-06-30 "liquid ink sloshing so it looks like a loading bar, not a
   scroll wheel"): two ink wave-crest strips ride the top of the fill, drifting opposite ways = slosh. */
#fuelBar .fuel-fill::before,#fuelBar .fuel-fill::after{content:"";position:absolute;left:-60%;right:-60%;
  background-repeat:repeat-x;pointer-events:none;
  background-image:radial-gradient(50% 120% at 50% 100%,var(--fuel-ink,var(--accent)) 70%,transparent 72%)}
#fuelBar .fuel-fill::before{top:-0.375rem;height:0.75rem;background-size:22px 12px;animation:fuelSlosh 2.6s linear infinite}
#fuelBar .fuel-fill::after{top:-0.25rem;height:0.625rem;opacity:.7;background-size:17px 10px;animation:fuelSlosh2 3.6s linear infinite}
@keyframes fuelSlosh{from{transform:translateX(0)}to{transform:translateX(22px)}}
@keyframes fuelSlosh2{from{transform:translateX(0)}to{transform:translateX(-17px)}}
#fuelBar.warn .fuel-fill{animation:fuelpulse 1.4s ease-in-out infinite}
#fuelBar.full{box-shadow:0 0 14px color-mix(in srgb,var(--block,#FF5A52) 55%,transparent)}
@keyframes fuelpulse{0%,100%{opacity:.75}50%{opacity:1}}
@media (prefers-reduced-motion: reduce){#fuelBar.warn .fuel-fill,#fuelBar .fuel-fill::before,#fuelBar .fuel-fill::after{animation:none}}

/* ---- Journey layout (step 3; Ken mock 2026-06-11) ---- */
.jrhead{display:flex;align-items:flex-start;justify-content:space-between;gap:1rem}
.jr-title,.jrph-name{font-family:ui-serif,Georgia,"Times New Roman",serif}
.jrprog{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-sm);padding:0.75rem 1rem;min-width:12.5rem}
.jrprog-l{font-weight:700;font-size:0.84375rem;margin-bottom:0.5rem}
.jrprog-bar{height:0.375rem;border-radius:3px;background:var(--surface2);overflow:hidden}
.jrprog-fill{height:100%;border-radius:3px;background:var(--accent);transition:width .5s var(--spring)}
.journey{display:flex;flex-direction:column;gap:0.25rem;max-width:61.25rem;position:relative;padding-left:0.5rem}
.journey::before{content:"";position:absolute;left:2.0625rem;top:0.625rem;bottom:0.625rem;width:0.125rem;background:color-mix(in srgb,var(--accent) 25%,var(--line))}
.jrsec{position:relative;padding:0.625rem 0 0.375rem}
.jrph{display:flex;align-items:center;gap:0.875rem;cursor:pointer;padding:0.25rem 0}
.jricon{width:3.25rem;height:3.25rem;border-radius:50%;border:2px solid;background:var(--surface);display:flex;align-items:center;justify-content:center;flex:none;position:relative;z-index:1}
.jrdot{width:1rem;height:1rem;border-radius:5px}
.jrph-t{flex:1;min-width:0}
.jrph-name{font-size:1.3125rem;font-weight:700;line-height:1.2}
.jrph-resp{color:var(--muted);font-size:0.8125rem;margin-top:0.125rem}
.jrchev{font-size:1rem;flex:none}
.jrsteps{margin:0.5rem 0 0.25rem 4.75rem;display:flex;flex-direction:column;gap:0.5rem}
.jrsec.collapsed .jrsteps{display:none}
.jrrow{display:flex;align-items:center;gap:0.8125rem;background:var(--surface);border:1px solid var(--line);border-radius:var(--r-sm);padding:0.8125rem 1rem;cursor:pointer;transition:transform .12s,border-color .12s}
.jrrow:hover{border-color:var(--line2);transform:translateY(-1px)}
.jrrow.cur{border-color:var(--accent);background:color-mix(in srgb,var(--accent) 9%,var(--surface));box-shadow:0 0 0 1px var(--accent)}
.jrrow.done .jrrow-t{text-decoration:line-through;color:var(--muted)}
.jrrow-t{flex:1;font-weight:600;font-size:0.90625rem;line-height:1.3}
.curbadge{display:inline-flex;align-items:center;gap:0.4375rem;font-size:0.65625rem;font-weight:800;letter-spacing:.1em;color:var(--accent2);background:color-mix(in srgb,var(--accent) 16%,transparent);border-radius:999px;padding:0.3125rem 0.6875rem;flex:none}
.curdot{width:0.4375rem;height:0.4375rem;border-radius:50%;background:var(--accent2)}
@media (max-width:700px){.jrsteps{margin-left:1.125rem}.journey::before{left:1.5625rem}.jricon{width:2.5rem;height:2.5rem}.jrhead{flex-direction:column}}

/* ---- Step-2 question screen breathing room (Ken 2026-06-11: "too squeezed") ---- */
.iqeyebrow{margin:0.625rem 0 1.125rem}
/* Reserve 2 lines for the question so a wrapping question doesn't shove Skip/Continue
   down → misclick → looks frozen → user bails before the plan generates (Ken 2026-06-26). */
.iqeyebrow + .q{margin:0 0 1.625rem;line-height:1.25;min-height:2.5em}
#iqAns{margin:0 0 0.875rem;padding:1rem 1.125rem;line-height:1.4;font-size:1.75rem;
  resize:none;overflow-y:auto;box-sizing:border-box}   /* 2× (Ken 2026-07-08 "make this font twice as large, easier to see") — the intake question IS the placeholder, so it reads big. HEIGHT IS SET IN JS (fitQ) to fit the whole question: a placeholder can't grow the box, so a fixed rows=2 sliced long questions mid-word on iPhone (Ken 2026-07-10). box-sizing so the JS scrollHeight height includes the padding. */
.iqcount{margin:0 0 1.125rem}
.stepnum.picknum{cursor:pointer}
.stepnum.picknum:hover{background:var(--accent);color:var(--accent-ink);border-color:transparent}

/* ---- Draft step status dropdown (Jira language; Ken 2026-06-11) ---- */
.stsel{background:var(--surface2);border:1px solid var(--line);border-radius:8px;color:var(--txt);font:inherit;font-size:0.71875rem;font-weight:700;padding:0.3125rem 0.5rem;cursor:pointer;flex:none}
.stsel.st-in_progress{color:var(--accent2);border-color:color-mix(in srgb,var(--accent) 45%,transparent)}
.stsel.st-blocked{color:var(--block,#FF5A52);border-color:color-mix(in srgb,var(--block,#FF5A52) 45%,transparent)}
.stsel.st-done{color:var(--good,#42C978)}
.uprow .stsel{margin-left:0.25rem}
.blockedrow{opacity:.75;border-left:3px solid var(--block,#FF5A52)}

/* ---- Wizard breathing room, ALL steps (Ken 2026-06-11: title needs air above its input) ---- */
#wizBody h2.q{margin:0.875rem 0 1.625rem;line-height:1.25}
#wizBody .f{margin-top:0}
#wizBody .wizfoot{margin-top:1.625rem}

/* ---- HOME: Attached + Timeline + Playlist + Hero (Ken canon 2026-06-11) ---- */
#queueHero{max-width:73.75rem;margin:1.625rem auto 2.5rem;padding:0 1.125rem}
.qh-attached{display:flex;align-items:center;gap:0.75rem;background:var(--surface);border:1px solid var(--line);border-radius:var(--r-sm);padding:0.75rem 1rem;margin-bottom:0.75rem}
.qh-attlbl{font-size:0.65625rem;font-weight:800;letter-spacing:.14em;color:var(--muted)}
.qh-attbody{color:var(--faint);font-size:0.8125rem}
.qh-timeline{display:flex;align-items:center;flex-wrap:wrap;margin:0 0 0.875rem;min-height:2.125rem}
.qh-grid{display:grid;grid-template-columns:21.25rem 1fr;gap:1rem;align-items:start}
@media (max-width:820px){.qh-grid{grid-template-columns:1fr}}
.qh-playlist,.qh-hero{background:var(--surface);border:1px solid var(--line);border-radius:var(--r);padding:0.875rem}   /* OPAQUE — was 92% (Ken 2026-06-21 "text needs to be easier to read, the background is making it too hard"): the 8% transparency let the z:-1 creature rain bleed through onto the text */
.qh-qhead{font-size:0.65625rem;font-weight:800;letter-spacing:.14em;color:var(--muted);margin:0.125rem 0.125rem 0.625rem}
.qh-count{color:var(--accent2);margin-left:0.25rem}
.qh-row{display:flex;align-items:center;gap:0.6875rem;width:100%;text-align:left;background:var(--surface);border:1px solid var(--line);border-radius:var(--r-sm);padding:0.75rem 0.8125rem;margin-bottom:0.5rem;color:var(--txt);font-weight:700}
.qh-row:hover{border-color:var(--line2)}
.qh-row.sel{border-color:var(--accent);box-shadow:0 0 0 1px var(--accent);background:color-mix(in srgb,var(--accent) 8%,var(--surface))}
/* COLLAPSIBLE LANES (Ken 2026-06-15): a chevron shows open/closed; click toggles. Multiple open. */
.qh-chev{flex:none;width:0.875rem;text-align:center;font-size:0.6875rem;color:var(--muted);transition:color .15s}
.qh-row.open .qh-chev,.qh-row:hover .qh-chev{color:var(--accent2)}
.qh-nm{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.qh-nm.struck{text-decoration:line-through;text-decoration-color:#ff5a4d;text-decoration-thickness:2.5px;color:var(--muted)}   /* lane done = name crossed out (Ken 2026-06-16) */
.qh-chev{color:var(--faint);font-weight:800;padding:0 0.1875rem}
.qh-lock{color:var(--faint);font-size:0.75rem;margin-top:0.375rem}
.qh-htitle{font-size:1.375rem;font-weight:800;margin:0.125rem 0 0.125rem}
.qh-done{background:color-mix(in srgb,var(--good,#42C978) 18%,transparent);color:var(--good,#42C978);border:1px solid color-mix(in srgb,var(--good,#42C978) 45%,transparent);border-radius:10px;font-weight:800;padding:0.5625rem 1rem}
.qh-done:hover{background:color-mix(in srgb,var(--good,#42C978) 28%,transparent)}
.qh-phase{display:flex;align-items:center;gap:0.625rem;width:100%;text-align:left;background:var(--surface);border:1px solid var(--line);border-radius:var(--r-sm);padding:0.75rem 0.875rem;margin-top:0.5rem;color:var(--txt)}
.qh-pname{font-size:0.6875rem;font-weight:800;letter-spacing:.12em;flex:1}
.qh-pcount{color:var(--muted);font-size:0.78125rem}

/* ---- Ferro: the oil creature stage (canvas; js/ferro.js) ---- */
.ferro-stage{position:fixed;inset:0;z-index:0;pointer-events:none}   /* the WHOLE viewport is the tank (Ken) */
.ferro-stage canvas{position:absolute;inset:0;width:100%;height:100%}
/* ALWAYS THE FRONTMOST LAYER (Ken 2026-06-21 "I want him in the most front z-wave of everything... he
   its always in front of everything for when we make mistakes... So he doesnt clip"): MAX z so the body
   + tentacles render OVER everything (no clipping, ever — the tentacle-cut-off he saw is gone). This
   reverses the 2026-06-20 z:6 (which sat below modals). pointer-events:none (.ferro-stage) keeps every
   click passing through, so being on top never blocks a control. Collision still stops his body at a
   visible border. Dim is one knob: --ferro-dim (1 = full strength). */
.ferro-bg{z-index:2147483647;opacity:var(--ferro-dim,1)}
/* CREATURE DURING LOADING ONLY (Ken 2026-07-05): when hidden (FERRO_OFF), he's invisible on normal
   screens and elegantly fades IN while a wait is happening, then fades OUT when it ends. */
body.ferro-hidden .ferro-bg{opacity:0;transition:opacity .6s var(--ease,ease)}
body.ferro-hidden.ferro-loading .ferro-bg{opacity:1}   /* (ambient path, now unused for loading) */
/* SUPPRESS the creature entirely — GDS video playing OR pointer at the footer (Ken 2026-07-10 "do not want the
   creature to appear when the video is shown / they click footer links"). !important beats the loading opacity:1
   override above, so it stays gone even mid-load; covers the ambient (#ferroBg) AND the loading storm (#ferroLoad). */
body.ferro-suppress #ferroBg, body.ferro-suppress #ferroLoad{ opacity:0!important; pointer-events:none; transition:opacity .3s var(--ease,ease); }
/* LOADER CREATURE (Ken 2026-07-07): the dedicated #ferroLoad stage — the full interactive engine mounted
   by core.js _loaderCreature, shown ONLY while a wait is on, fading in/out. Full-viewport tank, in front
   of the loader art; pointer-events:none (drag/throw listen on window, so interactivity still works). */
.ferro-loadcreature{position:fixed;inset:0;z-index:2147483646;pointer-events:none;opacity:0;transition:opacity .45s var(--ease,ease)}
body.ferro-loading .ferro-loadcreature{opacity:1}
/* Launcher layer: INSIDE #scLaunch's stacking context — z:0 lands it in FRONT of the
   ::before Whiskey photo (also z:0, painted first as generated content) and BEHIND the
   widgets (.launch is z:1). Same dim knob. */
#scLaunch .ferro-amb{z-index:0;opacity:var(--ferro-dim,1)}
.ferro-msg{position:relative;z-index:1}                              /* copy reads above the creature */
.ferro-wrap{min-height:38vh;display:flex;align-items:center;justify-content:center}
/* LOADER CENTERED both axes (Ken 2026-07-05 iPhone "I want this loader centered (vert,
   horiz), not at top"): the breakdown loader fills most of the stage so its flex-centering
   lands the chip+copy cluster mid-screen on every size. dvh (vh fallback) per fluid rule. */
.ferro-wrap.ferro-load{min-height:66vh;min-height:66dvh;flex-direction:column}
#wizBody .wizfoot{position:relative;z-index:1}                        /* Back stays clickable/legible */

/* ---- TICKET PRESENTATION (wizard step 3; Ken canon FINAL 2026-06-11) ---- */
.tkt{max-width:none;width:100%;margin:0;padding:0 0.375rem}   /* uses the screen like a dashboard (Ken correction #5) */
.tkt .qh-attached{margin-bottom:0.75rem}
.tkt-rail{display:none}   /* Ken 2026-06-11: hide the in-hero phase timeline — redundant with the lane list on the left */
.tkt-rail .pr-chip.cur{border-color:var(--accent);background:color-mix(in srgb,var(--accent) 14%,var(--surface));color:var(--accent2)}
.tkt-grid{position:relative;display:grid;grid-template-columns:minmax(20rem,40%) 1fr;gap:1rem;align-items:start}
/* NEVER CUT OFF (Ken 2026-07-03 screenshot: dots/verb/Share guillotined at the viewport edge):
   grid items default min-width:auto, so the hero column refused to shrink below its nowrap
   button row and pushed the whole card past the screen. min-width:0 lets columns shrink. */
.tkt-grid>*{min-width:0}
.tkt-grid.solo{grid-template-columns:1fr;max-width:42.5rem;margin:1.5rem auto 0}   /* goal-hero entry: one centred card (Ken 2026-06-16) */
.tkt-grid.solo:has(.goal-detail){max-width:66.25rem}   /* goal-detail explainer wants room for the 2-line copy (work order, Ken 2026-06-19) */
.tkt-grid.solo>.qh-playlist{display:none}   /* solo = hero only → an empty playlist never shows (Ken 2026-07-10 "when no tasks are there I want this hidden") */
/* NARROW BOARD = SWIPE PANES (Ken 2026-07-05: never playlist+hero together on a vertical
   layout): the grid slides between the two full-width panes; #draftBoard clips. The solo
   goal-hero card is exempt (already one thing). */
.pane-pager{display:none}   /* desktop shows both panes side-by-side — no pager; ≤860 the media query turns it on */
@media (max-width:860px){
  #draftBoard{overflow-x:hidden}
  /* CLIP the off-screen pane at the pane edge so it NEVER peeks at the screen edge (Ken 2026-07-05
     "I do not like the overlap showing"): the slider is exactly one pane wide; overflow-x:clip
     hides the parked pane without creating a scroll container (vertical scroll unaffected). */
  .tkt-slider{overflow-x:clip}
  .tkt-grid:not(.solo){display:flex;width:200%;gap:0;transform:translateX(0);
    transition:transform .3s var(--ease);align-items:start}
  .tkt-grid:not(.solo)>.qh-playlist,.tkt-grid:not(.solo)>.qh-hero{width:50%;flex:0 0 50%;box-sizing:border-box}
  .tkt-grid:not(.solo)>.qh-hero{padding-left:0.75rem}
  .tkt-grid:not(.solo)>.qh-playlist{padding-right:0.75rem}
  .tkt-grid:not(.solo).show-hero{transform:translateX(-50%)}
  /* SWIPE AFFORDANCE (Ken 2026-07-05 "make it obvious to swipe to see hero"): a two-dot pager +
     "swipe ↔" hint under the slider. The active pane's dot stretches to a pill; tap a dot to switch. */
  .pane-pager{display:flex;align-items:center;justify-content:center;gap:0.5rem;margin:0.75rem 0 0}
  .pp-dot{width:0.5rem;height:0.5rem;padding:0;border:none;border-radius:999px;
    background:color-mix(in srgb,var(--txt) 24%,transparent);transition:width .22s var(--ease),background .22s}
  .pp-dot.on{width:1.5rem;background:var(--accent)}
  /* SWIPE CUE (Ken 2026-07-05): the ↔ glyph only (no "swipe" text), BIG + bright so it stands out
     on the dark desk and reads as "swipe to see more". Gently sways to signal the gesture. */
  .pp-hint{margin-left:0.75rem;font-size:2.125rem;line-height:1;font-weight:700;color:#f3ead4;
    text-shadow:0 0.125rem 0.5rem rgba(0,0,0,.55);animation:ppSwipe 1.5s ease-in-out infinite}
@keyframes ppSwipe{0%,100%{transform:translateX(-0.375rem)}50%{transform:translateX(0.375rem)}}
@media (prefers-reduced-motion:reduce){.pp-hint{animation:none}}
}
.tkt-rows .qh-row{flex-wrap:wrap}
/* selected lane's UP NEXT, nested inline under its row in the queue (Ken: "this should go here") */
.qh-sub{margin:-0.125rem 0 0.75rem 0;padding-left:0;overflow:visible}   /* FLUSH with the lane title (Ken 2026-07-01 "No indentation on these"); nested depth still reads via rail hue + depth gauge, not left inset */
.qh-sub .upnext-label{margin-top:0.375rem;padding-top:0.5rem}
.qh-sub .qh-row{margin-bottom:0.375rem}
/* CURRENT step mirrored in the playlist + CLEARLY tied to the hero card (Ken 2026-06-11
   "this should also be in playlist but selected ... they should be clearly connect -> <-"):
   same blue as the hero, and arrows point across the gap toward each other. */
.cur-sel{position:relative;border:1px solid var(--accent)!important;
  background:color-mix(in srgb,var(--accent) 16%,var(--surface))!important;
  box-shadow:0 0 0 1px color-mix(in srgb,var(--accent) 40%,transparent),0 0 16px color-mix(in srgb,var(--accent) 22%,transparent)}
.cur-sel .uptitle{color:var(--accent2);font-weight:700}
/* the cur-sel highlight is the ONLY join between the row and the hero now — the SVG connector
   thread is fully removed (Ken 2026-06-20 "remove the connector line", rejected twice). */

.tkt-next{flex-basis:100%;color:var(--muted);font-weight:500;font-size:0.75rem;margin:0.25rem 0 0 2.3125rem}
.tkt-hero{padding:0.8125rem 1.25rem 1.125rem}   /* less empty space above the title (Ken refinement ~20%) */
/* INNER SECTION REMOVED (Ken 2026-06-16 "rip the stuff inside the hero ticket... move all that out to
   the hero widget. Get rid of inner section"): the .tkt-cur card chrome (its own bg/border/box) is
   gone — its contents now sit DIRECTLY in the hero widget (.qh-hero). One box, not a box-in-a-box.
   The element stays (gunshot targets .tkt-cur) but it's just a transparent content wrapper now. */
.tkt-cur{position:relative;background:none;border:none;border-radius:0;padding:0}
.tkt-cur .cs-title{font-size:1.1875rem}
/* HERO TITLE IS THE HERO (work order "Hero Ticket workbench" Concept A, 2026-06-30 — REVERSES the
   2026-06-19/20 "hide the title on the right, redundant with the left"): the step title is now the
   largest element on the panel. The new context bar (breadcrumb + dots + N of M) supplies the
   anchoring that made the bare repeat feel redundant before. Shown in both states; the reserved
   min-height (below) keeps the layout stable as you cross steps off. */
.tkt-grid:not(.solo) .tkt-cur .cs-row.no-drill{display:flex}
.tkt-grid:not(.solo) .tkt-cur .cs-title.td-bigt{font-size:1.875rem;font-weight:600;line-height:1.2}
/* GOAL DETAIL EXPLAINER (Ken 2026-06-19 work order — kill the empty-field trap on the goal /
   "Make it easier" view). Literal values from the work order; do not approximate. Left-aligned
   text, the goal stays handwritten, a single divider rule, then a real filled-blue button. */
.goal-detail{text-align:left;max-width:65rem;margin:0 auto;padding:1rem 1.625rem 1.625rem}
.goal-detail .gd-eyebrow{font-size:0.75rem;letter-spacing:.14em;font-weight:600;color:#8a7a5c;text-transform:uppercase;margin:0 0 0.25rem}
.goal-detail .cs-title{font-family:var(--ink-display,inherit);font-size:2.5rem;line-height:1.12}   /* goal stays handwriting, LARGE */
.goal-detail .gd-divider{height:0;border:none;border-top:1.5px solid #cdbf9d;margin:0.875rem 0 1.375rem}
.goal-detail .gd-lead{font-size:1.375rem;line-height:1.42;color:#4a4031;margin:0 0 0.875rem;max-width:61.25rem}
.goal-detail .gd-lead b{font-weight:600;color:#2b2114}
.goal-detail .gd-sub{font-size:1.1875rem;line-height:1.5;color:#6b5f48;margin:0 0 1.625rem;max-width:61.25rem}
.goal-detail .gd-actions{display:flex;justify-content:center;margin-top:0.375rem}
.gd-break{display:inline-flex;align-items:center;gap:0.625rem;background:#1e4d8c;color:#fff;border:none;
  border-radius:12px;padding:1rem 2.375rem;font-size:1.125rem;font-weight:600;cursor:pointer;transition:background .12s}
.gd-break:hover{background:#1a447d}
.gd-break:disabled{opacity:.7;cursor:default}
.tkt-cur .cs-acts{margin-top:0.875rem}
.tkt-row{padding:0.6875rem 0.5rem}
/* DRAG-TO-REORDER (Ken 2026-06-30): grab cursor + a clear insertion line on the row you'd drop before/after */
.tkt-row[draggable="true"]{cursor:grab}
.tkt-row.dragging{opacity:.45;cursor:grabbing}
/* DROP-LINE INDICATOR (Ken 2026-07-10 "a horizontal line to show where it will be inserted if you
   let go") — a bold accent insertion line with a soft glow, for STEP rows and WHOLE LANES alike.
   Replaces the old 2px inset shadows (invisible in practice — Ken's screenshot showed nothing). */
.tkt-row.drop-before,.tkt-row.drop-after,.qh-row.drop-before,.qh-row.drop-after{position:relative}
.tkt-row.drop-before::after,.tkt-row.drop-after::after,
.qh-row.drop-before::after,.qh-row.drop-after::after{
  content:"";position:absolute;left:0.25rem;right:0.25rem;height:0.2rem;border-radius:0.125rem;
  background:var(--accent);pointer-events:none;z-index:3;
  /* the .uprow::after HOVER CHEVRON rule leaks opacity:0 + top:50% + translateY into this ::after on
     TASK rows (lane .qh-row has no such rule — why only categories showed a line, Ken 2026-07-11).
     Every prop the chevron sets must be explicitly re-set here. */
  opacity:1;transform:none;
  box-shadow:0 0 0.375rem color-mix(in srgb,var(--accent) 55%,transparent)}
.tkt-row.drop-before::after,.qh-row.drop-before::after{top:-0.125rem;bottom:auto}
.tkt-row.drop-after::after,.qh-row.drop-after::after{top:auto;bottom:-0.125rem}
.qh-row.lane-dragging{opacity:.5}
.tkt-st{cursor:pointer;flex:none}
.tkt-st.st-in_progress{color:var(--accent2);border-color:color-mix(in srgb,var(--accent) 45%,transparent)}
.tkt-st.st-blocked{color:var(--block,#FF5A52)}
.tkt-acc{border:1px solid var(--line);border-radius:var(--r-sm);margin-top:0.625rem;background:var(--surface)}
.tkt-acch{display:flex;align-items:center;gap:0.625rem;width:100%;text-align:left;background:transparent;border:none;color:var(--txt);padding:0.8125rem 0.875rem}
.tkt-accn{font-size:0.6875rem;font-weight:800;letter-spacing:.12em;flex:1}
.tkt-accb{padding:0.125rem 0.625rem 0.625rem}
.tkt-acc.open .tkt-acch{border-bottom:1px solid var(--line)}
.tkt .stsel{width:auto;max-width:8.75rem}            /* app-wide select{width:100%} must not stretch the chip */
.qh-nm{min-width:5.625rem;color:var(--txt)}            /* the plan name never collapses in a wrapping row */
.tkt-next{order:9}

/* ---- EXECUTION DASHBOARD (Ken work order 2026-06-11) ---- */
.td-bar{display:flex;align-items:center;gap:0.875rem;margin:0.25rem 0 0.875rem}
.td-badge{display:inline-flex;align-items:center;gap:0.5rem;background:var(--surface);border:1px solid var(--line);border-radius:999px;padding:0.4375rem 0.875rem;font-weight:800;font-size:0.8125rem}
.td-dot{width:0.5rem;height:0.5rem;border-radius:50%;background:var(--good,#42C978)}
.td-help{color:var(--muted);font-size:0.8125rem}
.td-grid{display:grid;grid-template-columns:minmax(18.75rem,40%) 1fr;gap:1rem;align-items:start}
@media (max-width:860px){.td-grid{grid-template-columns:1fr}}
.td-dots{flex-basis:100%;display:flex;align-items:center;margin:0.375rem 0 0 2.3125rem}
.td-d{width:0.5625rem;height:0.5625rem;border-radius:50%;background:var(--surface2);border:1px solid var(--line2)}
.td-d.on{background:var(--accent);border-color:transparent}
.td-d.done{background:var(--good,#42C978);border-color:transparent}
.td-l{flex:1;max-width:2.125rem;height:0.125rem;background:var(--line)}
.td-htop{display:flex;align-items:center}
.td-big{width:2.5rem;height:2.5rem;font-size:1.125rem}
.td-bigt{font-size:1.375rem;line-height:1.25}
/* STABLE HERO TITLE (Ken 2026-06-16 "When I cross things off I don't want things moving around like
   the description section"): reserve a 2-line height for the hero title so the buttons + detail below
   sit at the SAME vertical spot whether the title is 1 line or 2, done or open — no jump as you cross
   steps off and move between them. align-items:flex-start keeps a short title pinned to the top. */
.tkt-cur .cs-row{align-items:flex-start}
.tkt-cur .cs-title.td-bigt{min-height:2.5em}
.td-done{font-size:0.9375rem;padding:0.75rem 1.625rem;box-shadow:0 0 18px color-mix(in srgb,var(--good,#42C978) 30%,transparent)}
.tkt-ptitle{font-size:1.625rem;margin:0.5rem 0.125rem 1.125rem}     /* project name OUTSIDE the widgets; breathing room below (Ken "Space here") */
.tkt-ptitle:has(+ .north-star:not([hidden])){margin-bottom:0.375rem}  /* tighten the gap when a North Star sits under the title */
/* NORTH STAR (Ken 2026-07-10) = the plan's one-paragraph guiding-goal summary under the title; click to edit. */
.north-star{max-width:62ch;margin:0 0.125rem 1rem;font-size:0.98rem;line-height:1.5;color:var(--muted,#5d564a);cursor:default}
.north-star.gen{opacity:.6;font-style:italic}
/* The summary is NOT click-to-edit and does NOT change on hover (Ken 2026-07-10 "for editing dont change it
   on hover. I just want a small edit icon to edit the text. You click that and then you can edit"): a small
   always-there ✎ button next to it is the ONE door into editing. */
.north-star .ns-edit{margin-left:0.4rem;padding:0 0.2rem;border:0;background:transparent;color:inherit;
  font-size:1.02em;line-height:1;opacity:.55;cursor:pointer;vertical-align:baseline}
.north-star .ns-edit:hover{opacity:1}
.north-star .ns-edit:focus-visible{outline:2px solid var(--accent,#244a85);border-radius:0.2rem;opacity:1}
textarea.north-star-edit{display:block;width:100%;max-width:62ch;margin:0 0.125rem 1rem;resize:vertical;font:inherit;line-height:1.5;padding:0.45rem 0.55rem;border:1.5px solid var(--accent,#244a85);border-radius:0.4rem;background:var(--surface,#fff);color:inherit}
.qh-row.lane-done{opacity:.72}
.tkt-partof{color:var(--muted);font-size:0.78125rem;margin:0.375rem 0 0.125rem}
.tkt-cur .tkt-break{margin:0.75rem 0 0;width:auto;display:inline-block;text-align:left}   /* left-align: inline-block shrinks to content + kills centered .breakdown auto-margins/centered text */
.tkt-break-off,.tkt-break-off:hover{opacity:.4;cursor:default;pointer-events:none;background:var(--surface2);border-color:var(--line);color:var(--muted);box-shadow:none;transform:none}  /* atomic step: breaking again is futile */

/* ---- STARTER TICKET (Ken 2026-06-11): first run = ONE ticket, "Brush your Teeth",
   blinking light + "Make it easier" CTA; pressing runs the normal breakdown flow ---- */
.tile.starter{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:0.5625rem;position:relative}
.st-light{width:0.6875rem;height:0.6875rem;border-radius:50%;background:#ffd34d;
  box-shadow:0 0 14px 4px rgba(255,211,77,.75);animation:stblink 1.1s steps(2,start) infinite}
@keyframes stblink{50%{opacity:.15;box-shadow:none}}
@media (prefers-reduced-motion: reduce){.st-light{animation:none}}
.st-cta{font-size:0.78125rem;font-weight:800;letter-spacing:.07em;text-transform:uppercase;color:var(--accent,#e8453c)}

/* (PERMANENT glowing borders RETIRED — Ken 2026-06-12 superseding his earlier always-on
   ask: "I want anything thing he can grab and only that to glow when he grabs it and
   only that... litterly only one box side at a time." Glow now lives in js/ferro.js
   _light(): grab-time only, one side in the whole world.) */

/* ---- CURRENT-STEP CONNECTOR (Ken 2026-06-12 "I want these to connect"): playlist's
   selected step row → hero card, one drawn thread; decorative, never blocks input ---- */
.tkt{position:relative}
/* .tkt-link (the cur-sel→hero SVG connector) fully removed — Ken 2026-06-20 "remove the connector line" */

/* ---- JIRA-STYLE TICKET detail — lives INLINE on the hero card now (Ken 2026-06-16
   "ripped out of [the drill page] and put on the hero card on main layout"); the .jt
   field styles below are shared by the (legacy) drill view and the hero's .tkt-detail ---- */
.tkt-detail{margin-top:0.875rem;padding-top:0.875rem;border-top:1px solid var(--line)}
/* DONE = GREYED OUT + DISABLED, NOT crossed out (Ken 2026-06-20 "Instead of crossing out everyghinf on
   a ticket I want you to grey it out disable it. But keep the playlist cross off part" — REVERSES the
   2026-06-17 "don't gray, cross out" pass): the hero's fields/buttons fade + go non-interactive. The
   PLAYLIST row keeps its red cross-off (.uptitle.struck, untouched). NOTES + Undo stay fully live. */
.tkt-cur.is-done .jt-row:not(.col),
.tkt-cur.is-done #dBreak,
.tkt-cur.is-done .cs-share,
.tkt-cur.is-done .foot-status,
.tkt-cur.is-done .cs-clar{pointer-events:none;opacity:.4;filter:grayscale(.6)}
/* NOTES STAYS LIVE + full-colour on done (Ken 2026-06-18 "remain active on done and not done... see
   and enter notes regardless") — re-enable + un-grey it inside the locked detail. */
.tkt-cur.is-done .jt-row.col{opacity:1;filter:none}
.tkt-cur.is-done .jt-row.col,.tkt-cur.is-done .jt-row.col textarea{pointer-events:auto}
/* Undo never dims — the one live escape hatch */
.tkt-cur.is-done #dDone{opacity:1!important;pointer-events:auto!important;filter:none!important}
.jt .jt-row{display:flex;align-items:center;gap:0.75rem;margin:0.75rem 0}
.jt .jt-row.col{flex-direction:column;align-items:stretch;gap:0.4375rem}
.jt .jt-lbl{font-size:0.71875rem;font-weight:800;letter-spacing:.08em;color:var(--muted);text-transform:uppercase;min-width:5.5rem}
.jt input,.jt textarea{font:inherit;background:var(--surface2,#10182a);border:1px solid var(--line);border-radius:10px;padding:0.5625rem 0.75rem;color:var(--txt);flex:1;width:100%}
.jt textarea{resize:none;overflow:hidden}   /* fixed height — the Notes box must NOT jump/wiggle across a done re-render (Ken 2026-06-18); long notes scroll inside */
.jt .jt-thread{display:flex;flex-direction:column;gap:0.375rem}
.jt .jt-c{background:color-mix(in srgb,var(--surface) 80%,transparent);border:1px solid var(--line);border-radius:10px;padding:0.5rem 0.6875rem;font-size:0.84375rem}
.jt .jt-add{display:flex;gap:0.5rem}
.jt .jt-add input,.jt .jt-add textarea{flex:1}
/* inline title editing on the ticket page (Ken: "Edit is inline not another window") */
.jt .jt-title{background:none;border:1px solid transparent;border-radius:8px;padding:0.125rem 0.375rem;margin-left:-0.375rem;
  font-size:1.375rem;font-weight:800;color:var(--txt);width:100%}
.jt .jt-title:hover{border-color:var(--line)}
.jt .jt-title:focus{outline:none;border-color:var(--accent,#2D7CFF);background:var(--surface2,#10182a)}

/* FIX-IT CONSOLE (Ken 2026-06-12 "tell the AI what's wrong, it adjusts the tickets" —
   emergency last resort): one quiet line under the map, never a chat window. */
.fixit{display:flex;gap:0.625rem;align-items:center;margin:1rem 0.125rem 0}
.fixit input{flex:1;font-size:0.875rem;padding:0.625rem 0.8125rem;background:color-mix(in srgb,var(--surface) 70%,transparent)}
.fixit button{white-space:nowrap}
/* hero card = the one door INTO the ticket (rows only select — Ken 2026-06-12) */
.tkt-cur .cs-row{cursor:pointer}

#leGear{display:none}   /* hidden until the layout_editor flag/override enables it (Ken 2026-06-16) */
#leGear.le-armed{display:inline-flex;color:#fff;background:var(--accent,#2D7CFF);border-radius:9px}   /* obvious when on */
/* ============ LAYOUT EDITOR (Ken 2026-06-16) — drag/resize/reposition ANY element + per-breakpoint save ============ */
#lePanel{position:fixed;top:3.375rem;right:0.875rem;width:18.75rem;max-width:calc(100vw - 1.75rem);background:var(--surface,#101F3A);border:1px solid var(--line);border-radius:14px;padding:0.875rem 0.9375rem;z-index:10001;box-shadow:0 16px 48px rgba(0,0,0,.55);font-size:0.875rem;color:var(--txt)}
.le-h{font-weight:800;margin-bottom:0.625rem}
.le-bp{color:var(--muted);font-weight:600;font-size:0.75rem;text-transform:uppercase;letter-spacing:.05em}
.le-row{display:flex;align-items:center;gap:0.5625rem;margin:0.5rem 0;cursor:pointer}
.le-hint{color:var(--muted);font-size:0.78125rem;line-height:1.45;margin:0.375rem 0 0.75rem}
.le-btns{display:flex;flex-wrap:wrap;gap:0.5rem}
.le-btns button{background:var(--surface2,#17294A);border:1px solid var(--line);color:var(--txt);border-radius:9px;padding:0.5rem 0.6875rem;font:inherit;font-size:0.8125rem;cursor:pointer}
.le-btns button:hover{border-color:var(--accent,#2D7CFF)}
.le-out{margin-top:0.75rem;background:#06122a;border:1px solid var(--line);border-radius:8px;padding:0.5625rem 0.625rem;font:11.5px/1.45 ui-monospace,Menlo,monospace;white-space:pre-wrap;max-height:12.5rem;overflow:auto;color:var(--muted)}
/* edit-mode banner — makes it unmistakable you're editing */
#leBanner{position:fixed;left:0;right:0;top:0;z-index:10000;background:var(--accent,#2D7CFF);color:#fff;font-size:0.8125rem;font-weight:600;text-align:center;padding:0.4375rem 0.75rem;box-shadow:0 4px 18px rgba(0,0,0,.4)}
#leBanner #leBx{margin-left:0.5rem;text-decoration:underline;cursor:pointer}
#leBanner .le-ur{margin:0 0.125rem;padding:0.125rem 0.5625rem;font:inherit;font-weight:700;color:#fff;background:rgba(255,255,255,.16);border:1px solid rgba(255,255,255,.4);border-radius:7px;cursor:pointer}
#leBanner .le-ur:hover:not(:disabled){background:rgba(255,255,255,.28)}
#leBanner .le-ur:disabled{opacity:.4;cursor:default}
body.le-edit{cursor:default}
/* hover + selection cues — anything you point at lights up */
body.le-edit .le-hot{outline:1.5px dashed color-mix(in srgb,var(--accent,#2D7CFF) 75%,transparent);outline-offset:2px;cursor:move}
body.le-edit .le-sel{outline:2px solid var(--accent,#2D7CFF)!important;outline-offset:2px;cursor:move;touch-action:none}
body.le-edit *{cursor:move}
body.le-edit .le-ovis{overflow:visible!important}   /* let scaled widgets overflow their parents instead of clipping */
/* the dedicated per-widget control toolbar (move · rotate · size · border · reset) */
#leTools{position:fixed;left:50%;bottom:1.25rem;transform:translateX(-50%);z-index:10002;display:flex;flex-wrap:wrap;justify-content:center;align-items:center;gap:0.1875rem;max-width:calc(100vw - 1rem);padding:0.375rem 0.5rem;background:var(--surface,#101F3A);border:1px solid var(--accent,#2D7CFF);border-radius:12px;box-shadow:0 10px 30px rgba(0,0,0,.6);touch-action:none}
#leTools[hidden]{display:none}   /* the display:flex above out-specifies the UA [hidden] rule — restore it so the toolbar hides when edit mode is off (Ken 2026-06-17) */
#leTools button{width:2.125rem;height:2.125rem;display:grid;place-items:center;font-size:0.9375rem;line-height:1;border:none;border-radius:8px;background:var(--surface2,#17294A);color:var(--txt);cursor:pointer;touch-action:manipulation}
#leTools button:hover{background:var(--accent,#2D7CFF);color:#fff}
#leTools button:active{transform:scale(.92)}
#leTools .le-reset{background:transparent;color:var(--muted)}
#leTools .le-sep{width:0.0625rem;height:1.375rem;background:var(--line);margin:0 0.1875rem}
/* DEDICATED BORDER WIDGET (Ken 2026-06-22): a clear ON/OFF + thickness panel above the toolbar. */
#leBorder{position:fixed;left:50%;bottom:4.625rem;transform:translateX(-50%);z-index:10002;display:flex;align-items:center;gap:0.4375rem;padding:0.375rem 0.75rem;background:var(--surface,#101F3A);border:2px solid var(--accent,#2D7CFF);border-radius:12px;box-shadow:0 10px 30px rgba(0,0,0,.6);font-size:0.8125rem;color:var(--txt);touch-action:none}
#leBorder[hidden]{display:none}
#leBorder.le-bd-active{border-color:var(--good,#4f6e3b)}
#leBorder .le-bd-lbl{font-weight:800;letter-spacing:.02em;white-space:nowrap}
#leBorder button{min-width:2.125rem;height:1.875rem;padding:0 0.625rem;display:grid;place-items:center;font-size:0.875rem;font-weight:800;line-height:1;border:none;border-radius:8px;background:var(--surface2,#17294A);color:var(--txt);cursor:pointer;touch-action:manipulation}
#leBorder button:hover{background:var(--accent,#2D7CFF);color:#fff}
#leBorder button:active{transform:scale(.92)}
#leBdToggle{min-width:3.5rem!important;letter-spacing:.06em}
#leBdToggle.on{background:var(--good,#4f6e3b)!important;color:#fff}
#leBorder .le-bd-num{min-width:2.125rem;text-align:center;font-weight:700;opacity:.85}
#leBorder .le-sep{width:0.0625rem;height:1.25rem;background:var(--line);margin:0 0.125rem}
/* ALL BORDERS ON BY DEFAULT (Ken 2026-06-22 "Turn all borders on by default and I will undo them as I
   want to unblock the creature"): when body.le-allbd is set (the layout editor is ENABLED + the
   all-borders mode is on — see layoutedit.js applyAllbd), every major box gets the inset-shadow border
   the creature reads as a WALL, so he's blocked everywhere by default. Ken turns a box's border OFF in
   the editor (bd=0 → leStyle box-shadow:none!important, which out-specifies this) to carve a creature
   PATH. Gated to body.le-allbd so normal users (editor flag off at release) never see black borders. */
body.le-allbd :is(.lgoal,.lart,.lshelf,.lchip,.tile,.wrap,.qh-playlist,.qh-hero,.tkt-grid,.tkt-cur,
  .spotwrap,.rail,.drawer,.authcard,.nudge,.nudge-card,.obs,.planwidget,.buddywidget){
  box-shadow:inset 0 0 0 4px var(--le-bd,#1a1a1a)!important;   /* !important so it beats ID-scoped ink card shadows; the per-box OFF (leStyle, body.le-allbd-prefixed, same specificity + later) still wins. ALL args single-class so :is() stays (0,1,0) — a compound like ".modal .card" would inflate it past the OFF rule. */
}
/* ============ LAUNCHER 2×2 GRID (Ken 2026-06-22 "I want these in a 2x2 widget in a parent widget that
   holds all 4 together") — desktop only (≥1024px); iPhone/iPad keep their stacked layout. The .launch
   PARENT is a 2-column grid: the headline spans the top, then the left column (.lstart = the goal
   composer over the example chips) and the right column (.lright = the breakdown sketch over the My-plans
   shelf) give the 2×2 = Composer·Sketch / Chips·Plans. Replaces the old absolute free-positioning + the
   superseded layout-editor baked coords. ============ */
/* IDEA RAIN — shared chip rules (hoisted out of the desktop media block 2026-07-05: the
   rain now runs on EVERY size; only the CONTAINER differs — bare desk on desktop, a
   contained widget card on phone/tablet per Ken's iPhone ask). */
#scLaunch .lchips.is-rain .rainchip{position:absolute; top:0; will-change:transform; white-space:nowrap; margin:0;}
#scLaunch .lchips.is-rain .rainchip:hover{z-index:3; box-shadow:0 4px 14px rgba(0,0,0,.25);}
.rainchip.rain-amber{border-color:var(--ink-amber,#d7a54a); color:var(--ink-amber,#d7a54a);}
.rainchip.rain-blue{border-color:var(--accent,#378ADD); color:var(--accent,#378ADD);}
.rainchip.rain-coral{border-color:var(--ink-coral,#e0745c); color:var(--ink-coral,#e0745c);}
.rainchip.rain-teal{border-color:var(--ink-teal,#4e9e8f); color:var(--ink-teal,#4e9e8f);}
.rainchip.rain-violet{border-color:var(--ink-violet,#8a6fc8); color:var(--ink-violet,#8a6fc8);}
.rainchip.rain-rose{border-color:var(--ink-rose,#c86f8e); color:var(--ink-rose,#c86f8e);}

/* PHONE/TABLET SECTION ORDER (Ken 2026-07-05: "hero breakdown ABOVE our prompt widget…
   below our logo and slogan"): the stacked bands dissolve the two column wrappers
   (display:contents) so the real blocks order directly — headline → SKETCH → composer →
   rain → plans. Desktop grid (≥1024) untouched. */
@media(max-width:1023px){
  #scLaunch .launch{display:flex;flex-direction:column}
  #scLaunch .lstart,#scLaunch .lright{display:contents}
  #scLaunch .launchhead{order:1}
  #scLaunch .nudge-card{order:2}
  #scLaunch .lart{order:3;margin-top:1rem;width:100%}
  #scLaunch .lgoal{order:4;width:min(35rem,100%);margin-top:1rem}
  #scLaunch .lchips{order:5}
  /* CREAM CARD ON MOBILE TOO (Ken 2026-07-10 "iPhone plans widget must look like the web one"): give
     the shelf the same cream panel + black border as the desktop grid so the widget reads identically
     across interfaces (only the position differs — stacked here, right-column there). */
  #scLaunch .lshelf{order:6;margin-top:1rem;background:var(--surface);border:2px solid #1a1a1a;border-radius:0.875rem;padding:1rem 1.125rem}
}

/* PHONE/TABLET RAIN CARD (Ken 2026-07-05 iPhone: "not raining… not in a widget… not
   restrained"): the tags rain INSIDE a bounded cream widget, like the composer and the
   plans shelf — never an endless bare list. Fluid height; overflow clipped. */
@media(max-width:1023px){
  /* TRANSPARENT like the web (Ken 2026-07-05 round 2: "background gone… only the rain
     showing"): the region stays BOUNDED + clipped (the restrained part), but the
     container itself is invisible — rain straight on the walnut, matching desktop. */
  #scLaunch .lchips.is-rain{display:block; position:relative; overflow:hidden; padding:0;
    height:34dvh; min-height:16rem; max-height:none;
    background:transparent; border:none; box-shadow:none; border-radius:0;}
}

@media (min-width:1024px){
  /* ROW-PAIRED GRID (Ken 2026-06-30 "prompt+drawing next to each other same size; suggestions+plan list
     below; a vertical parent of horizontal rows; scroll by default if it doesn't fit"). The .lstart /
     .lright wrappers become display:contents so their 4 children are DIRECT grid cells, letting us pair
     them by ROW: [prompt | drawing] over [suggestions | plans]. Scoped to #scLaunch to out-specify the
     base `#scLaunch .launch{display:block}`. */
  #scLaunch .launch{display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr);
    /* ART BY THE HEADLINE + TALL PLANS (Ken 2026-07-10 "move the animation to the right of the headline…
       extend the plans widget so it takes up two vertical blocks"): the sketch rides the header row to the
       right of the headline; the plans shelf spans BOTH body rows on the right. Left column stacks
       headline → composer → rain. */
    grid-template-areas:"head art" "prompt plans" "sugg plans";
    grid-template-rows:minmax(0,1fr) minmax(0,1fr) minmax(0,1fr);
    align-items:stretch; gap:1.25rem 2.5rem; padding:1.625rem 3rem 2.5rem; max-width:83.75rem; margin:0 auto;
    height:100%; box-sizing:border-box; overflow:auto;}   /* definite height = the STAGE under the topbar; the THREE equal 1fr rows split the space EQUALLY → the art cell matches the composer cell (Ken 2026-07-10 "resize the animation to the same size for consistency"), all on-screen, bottom padding = the air gap */
  #scLaunch .launchhead{position:static; grid-area:head; max-width:none; margin:0; align-self:start;}
  /* wrappers dissolve → their children join the parent grid directly */
  #scLaunch .lstart, #scLaunch .lright{display:contents;}
  #scLaunch .lgoal{grid-area:prompt; position:static; width:auto; height:100%; align-self:stretch;}
  /* the white input fills ~90% of the composer card; the "Plan it" footer takes the rest (Ken 2026-06-30) */
  #scLaunch .lgoal-in{flex:1; min-height:0;}
  /* SAME SIZE AS THE COMPOSER (Ken 2026-07-10): the art fills its cell exactly like .lgoal fills the
     prompt cell — same column width, same 1fr height → the two hero cards read as a matched pair. */
  #scLaunch .lart{grid-area:art; position:static; align-self:stretch; justify-self:stretch; width:100%; height:100%; min-height:0;}
  /* the two BOTTOM cells are black-bordered CARDS, same size as the top row (Ken 2026-06-30). */
  #scLaunch .lchips, #scLaunch .lshelf{grid-area:unset; height:100%; min-height:0; align-self:stretch;
    background:var(--surface); border:2px solid #1a1a1a; border-radius:0.875rem; padding:1rem 1.25rem; margin:0;}
  /* chips flow horizontally then WRAP down (Azure-tag style) + CENTERED in the card (Ken 2026-06-30) */
  #scLaunch .lchips{grid-area:sugg; overflow-y:auto; display:flex; flex-flow:row wrap; justify-content:center; align-content:safe center; gap:0.75rem; max-height:none;}   /* SAFE center: centered when it fits, top-anchored scroll when chips overflow (plain center clips the first row) */   /* the base .lchips max-height:13rem CAPPED this cell → it rendered short; uncap so the 40vh equal-size rule wins (Ken 2026-07-01 "all 4 the same size") */
  /* ROTATING CAROUSEL (Ken 2026-07-01 "rotating carousel — only show 3 rows at a time, same sized widget"):
     when JS wraps the chips, the cell becomes a column that CENTERS a 3-row view; the view clips and the
     inner track marquees. Cell size is unchanged — only the inner window is 3 rows. */
  #scLaunch .lchips.is-carousel{overflow:hidden; flex-flow:column nowrap; justify-content:stretch; align-items:stretch; align-content:normal; gap:0;}

  /* IDEA RAIN (Ken 2026-07-01 "raining like the matrix (Not green color)… 'ideas' raining"): the
     suggestions card becomes a rain field — chips fall in loose lanes (JS initIdeaRain, WAAPI
     transform-only), each with a random pencil hue from the ink palette + a random size. Replaces
     the 3-row carousel (its CSS below stays dormant for restore). */
  #scLaunch .lchips.is-rain{display:block; position:relative; overflow:hidden; padding:0;
    background:transparent; border:none; box-shadow:none;}   /* NO CARD (Ken 2026-07-03 "make our rain have no background"): the tags fall straight on the walnut desk, like the breakdown sketch's transparent drawing */

  #scLaunch .lchips.is-carousel .lchip-view{flex:1 1 auto; min-height:0; width:100%; overflow:hidden;}   /* fill the whole cell — use the real estate */
  #scLaunch .lchips.is-carousel .lchip-track{display:flex; flex-flow:row wrap; justify-content:center; align-content:flex-start; column-gap:0.75rem; row-gap:0.75rem; will-change:transform;}
  #scLaunch .lchips.is-carousel .lchip{display:inline-flex; align-items:center; justify-content:center;}   /* taller pills center their text (min-height set by JS to fill 1/3 of the card) */
  #scLaunch .lchips.is-carousel .lchip-break{flex-basis:100%; height:0;}   /* forces the clone onto a fresh row so the loop is seamless */
  #scLaunch .lshelf{grid-area:plans; display:flex; flex-direction:column;}   /* .lplans inside scrolls */
  #scLaunch .lshelf:has(.lplans:empty){display:flex;}
  /* GUARANTEED EQUAL + ALWAYS ON-SCREEN (Ken 2026-07-01 "bottom boxes are cut off... small air gap
     at bottom" — supersedes the fixed 40vh, which was equal but overflowed): each cell is height:100%
     of its minmax(0,1fr) track (set above), the two tracks are equal by construction, and the grid
     itself is height:100% of the stage → same size AND inside the viewport at every size; the .launch
     bottom padding is the air gap. (The old "stretch wasn't landing" mystery was ONLY the base .lchips
     max-height cap, uncapped above — never re-add a fixed cell height to fix equality.) */
  #scLaunch .lgoal, #scLaunch .lart, #scLaunch .lchips, #scLaunch .lshelf{min-height:0;}
  /* the wizard board keeps its own authored transform (a different screen, untouched) — but ANCHOR the
     1.2× scale at the TOP so it grows DOWNWARD (Ken 2026-07-10 "top is cut off"): the default centre
     origin pushed the plan title up under the topbar. */
  #scWizard .wrap{transform:translate(10px,50px) scale(1.2); transform-origin:top center}
}

/* ═══════════════════════════════════════════════════════════════════════════
   RESPONSIVE PROPORTIONALITY PASS (Ken 2026-06-18 "everything proportional to the
   available screen size — iPhone/Android, iPad, Mac, PC, long (portrait) + wide
   (landscape). I want it all perfect"). From the responsive-audit sweep. Every rule
   is breakpoint- or orientation-SCOPED so the validated desktop (≥1024, authored)
   layout stays untouched; these only repair narrower/shorter viewports, the tablet
   band, and mobile dynamic-viewport height.
   ═══════════════════════════════════════════════════════════════════════════ */

/* mobile dynamic viewport: 100vh includes the URL bar on mobile Safari, hiding bottom
   action rows under the chrome. dvh = the real visible height (old engines keep 100vh). */
.app{height:100dvh}
.drawer{height:100dvh}
.col{max-height:calc(100dvh - 20rem)}

/* baked layout-editor DESKTOP coords must not overflow narrower laptops/iPads. The board
   (#scWizard .wrap) was scaled 1.2× (→1176px) which overflows below ~1200px → horizontal
   scroll + the Done button clipped. Drop the scale there; Ken's authored ≥1200 view stays. */
@media (min-width:1024px) and (max-width:1199px){
  #scWizard .wrap{transform:translate(10px,50px)}
}
/* the launcher composer was scaled 1.4× + nudged for a very wide screen — neutralize the
   two overflowing nudges in the 1024–1339 gap (planrow's transform is left alone: it carries
   the hover-hold fix). */
/* (the 1024–1339 #launchForm{transform:none} override was REMOVED 2026-06-21 — it reset the OLD
   baked form; Ken's desktop coords (translate(180,-150) scale(1.6), bake above) now apply across all ≥1024.) */

/* TABLET BAND (641–1023): the workspace map board only stacked at ≤640, so iPad portrait
   (768) kept 3×300px columns = horizontal overflow. Stack it through the whole band. */
@media (min-width:641px) and (max-width:1023px){
  .board{flex-direction:column;overflow-x:visible;gap:0.875rem}
  .board .col{width:100%;min-width:0;max-width:42.5rem;margin:0 auto;max-height:none}
}

/* MODALS: a safe height ceiling + scrolling body so a tall modal (feedback/settings) never
   pushes its footer buttons off a short screen. Harmless on desktop — only engages when the
   content is actually taller than the viewport. */
.modal .box{max-height:calc(100dvh - 2rem);display:flex;flex-direction:column}
.modal .box>.c{overflow-y:auto;-webkit-overflow-scrolling:touch;flex:1 1 auto}

/* SHORT VIEWPORT (phone landscape / short laptops): let content scroll instead of being
   trapped in fixed-height boxes. */
@media (max-height:560px){
  .col{max-height:none}
  .board{flex-direction:column}
  .spotwrap{min-height:auto;padding:0.875rem 0.625rem}
  #sitGuest,#shareGuest{place-items:start center;padding:0.75rem}
  .sitg-card{padding:1.125rem}
}
@media (max-height:520px){
  .modal .box{max-height:calc(100dvh - 1rem)}
  #fbNote{min-height:5rem;max-height:30vh}
}

/* PHONE PORTRAIT ≤480 — proportional spacing + stacking on the narrowest screens. */
@media (max-width:480px){
  .cs-actions{flex-direction:column;gap:0.625rem}
  .cs-actions>.cs-done,.cs-actions>.hero-break,.cs-actions>.ai-verb{width:100%;flex:none;font-size:0.875rem;padding:0.8125rem 0.875rem}
  .jt .jt-row{flex-wrap:wrap;gap:0.375rem 0.75rem}
  .jt .jt-lbl{min-width:0}
  .jt input,.jt textarea{width:100%;flex:1 1 100%}
  .tabs{display:flex;flex-wrap:wrap;width:max-content;max-width:100%}
  .tabs button{padding:0.4375rem 0.75rem;font-size:0.8125rem}
  .spot{padding:1.5rem 1.125rem} .spot.done{padding:1.875rem 1.125rem}
  .spot-title{font-size:clamp(1.25rem,5.5vw,1.6875rem)} .spot-reason{max-width:100%}
  .wizfoot{gap:0.5rem;flex-wrap:wrap}
  .wrap{padding:1.25rem 1rem 4.5rem}
  #fbNote{min-height:7.5rem;max-height:34vh}
  /* GOAL-DETAIL explainer fits a phone: tighter padding, fluid handwritten title, smaller copy
     (responsive-audit, Ken 2026-06-19). */
  .goal-detail{padding:0.875rem 1rem 1.25rem}
  .goal-detail .cs-title{font-size:clamp(1.625rem,8vw,2.5rem)}
  .goal-detail .gd-lead{font-size:1.0625rem}
  .goal-detail .gd-sub{font-size:0.9375rem}
  .gd-break,.cs-share{width:100%;justify-content:center}   /* full-width like the other hero buttons */
  #wizBody .q{font-size:clamp(1.25rem,5.6vw,1.5625rem)}             /* the intake question wraps cleanly at 320 */
}

/* the AI dock clears the iOS home indicator + fits the gutter */
@media (max-width:640px){
  .dock{padding:0.75rem 0.875rem calc(0.75rem + env(safe-area-inset-bottom));gap:0.5rem}
}

/* ADMIN thumbs-up chip on the step-3 footer (Ken 2026-06-22) — hidden for non-admins (.ghost base). */
.admin-like{font-weight:700}
.admin-like.on{color:var(--good,#4f6e3b)}

/* ── FERRO not cut off (Ken 2026-06-24 "I want this fixed he's cut off") ──
   The creature is painted onto the full-viewport #ferroBg canvas; his FLOOR is the stage
   height (resize() derives H from stage.getBoundingClientRect()). His meatball body +
   dangling tentacle-legs extend BELOW his center, so when he rested/roamed to the very
   bottom his lower body was drawn past the canvas edge and clipped (and at z-index max he
   sits in front of the bottom cards). Reserve a bottom band so his whole body stays on
   canvas — resize() picks this up automatically (the canvas buffer shrinks with the stage).
   TUNABLE: raise the inset to lift his floor higher, lower it to let him sit closer to the
   bottom. (Verified live: bottom:6rem shrinks the stage vh→vh-96 and the canvas follows.) */
#ferroBg.ferro-bg{ bottom:6rem; }

/* ── GLOBAL ("whole-plan") assistant identity (Ken 2026-06-24 "I want a global llm somewhere ... it
   only knows about everything, whereas the other ones specialize") ──
   The hero chat (.cs-clar) is the ONE assistant that sees + edits the ENTIRE plan (its own placeholder:
   "…I'll adjust the plan"). So mark it as the global view. The specialized surfaces are "🔨 Break it
   down" + the per-step work (one step at a time) and the colour-coded lanes (one area each). This is a
   small label at the top of the existing chat block — presentation only, no layout break, and it stacks
   fine on phones (the .cs-clar-row input is untouched). Placed here (not Ken's blue box) by request. */
/* "Sees your whole plan" pill REMOVED (Ken 2026-06-30 "get rid of this"). */

/* ── HERO REDESIGN (Ken 2026-06-30): the ASK box is the large welcoming CENTERPIECE at the top;
   a number BADGE links the hero to the selected playlist step ("1 ↔ 1", no long title needed);
   Notes spans the full width of the card. ──────────────────────────────────────────────── */
/* number badge = the visual connector to the highlighted playlist row */
.cs-heronum{display:inline-flex;align-items:center;justify-content:center;width:2.375rem;height:2.375rem;
  border-radius:999px;font-weight:800;font-size:1.125rem;margin:0 0 0.625rem;
  color:var(--accent,#244a85);background:var(--accent-soft,rgba(36,74,133,.12));
  border:2px solid color-mix(in srgb,var(--accent,#244a85) 45%,transparent);line-height:1}
/* the ask box, as the centerpiece: big, inviting, full width */
.cs-hero-ask{margin:0 0 1.125rem}
.cs-hero-ask .cs-clar-row input,.cs-hero-ask .cs-clar-row textarea,
.plan-chat .cs-clar-row input,.plan-chat .cs-clar-row textarea,           /* the global plan-chat input shares the hero's height (Ken 2026-07-07 "same height, length can differ") */
#dClarIn{font-size:1rem;padding:1rem;min-height:3.625rem;border-radius:0.75rem;width:100%}   /* taller = more inviting; all rem (Ken refinement) */
#dClarIn::placeholder{opacity:.85}
#dClarIn::-webkit-search-cancel-button,#dClarIn::-webkit-search-decoration{-webkit-appearance:none;display:none}
.cs-hero-ask .cs-clar-row{gap:0.625rem}
.cs-hero-ask .cs-clar-row #dClarGo{padding:0 1.125rem;font-weight:700;white-space:nowrap}
/* NOTES — full width, taller, clean (Ken 2026-06-30 "re-design from scratch, span left to right") */
.tkt-detail{width:100%}
.jt .jt-row.col{width:100%}
#jtDesc{width:100%;min-height:6rem;font-size:0.9375rem;line-height:1.5;padding:0.75rem 0.875rem;border-radius:12px;
  box-shadow:none;background:rgba(255,253,247,.65);border:1px solid color-mix(in srgb,var(--accent,#244a85) 18%,transparent)}

/* ============ HERO TICKET WORKBENCH — Concept A (work order 2026-06-30) ============
   Step is the hero; assist kept prominent (Ken); status/note/share demoted to a light footer rail.
   Reuses existing tokens; --ink-amber/espresso come from ink.css, with safe fallbacks here. */
/* HERO NAVIGATOR (Ken 2026-07-10 "On hero I want a next and before and home navigation... Make the tool
   bar black at top where the naviagor lives"): a BLACK bar across the top of the hero card carrying the
   same ‹ ⌂ › glyphs as the site topbar — cream on black, same hover. Ends hide rather than disable, so
   the bar shows only the moves that exist (never a dead button). */
.hero-nav{display:flex;align-items:center;gap:0.15rem;background:#000;border-radius:0.55rem;
  padding:0.1rem 0.3rem;margin:0 0 0.75rem;min-height:2.4rem}
.hero-nav .nav-arrow{font-size:1.9rem;line-height:1;font-weight:800;padding:0 0.55rem;
  color:#e9e1ce;background:transparent;border:0;border-radius:0.35rem;cursor:pointer}
.hero-nav .nav-arrow:hover{color:#fff;background:rgba(255,255,255,.09)}
.hero-nav .nav-arrow:focus-visible{outline:2px solid #fff;outline-offset:-2px}
.hero-nav .nav-arrow[hidden]{display:none!important}
.hero-ctx{display:flex;align-items:baseline;justify-content:space-between;gap:0.75rem;flex-wrap:wrap;margin:0.125rem 0 0.625rem}
.hctx-crumb{font-size:0.875rem;font-weight:600;color:var(--ink-amber,var(--accent));letter-spacing:.01em;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:60%}
.hctx-prog{display:inline-flex;align-items:center;gap:0.5rem}
.hctx-dots{display:inline-flex;align-items:center;gap:0.375rem}
.hctx-nm{font-size:0.75rem;color:var(--muted);white-space:nowrap}
/* progress dots — ochre to match the mock: current/done filled ochre, future hollow ochre ring */
.hctx-dots .td-d{width:0.5625rem;height:0.5625rem;background:transparent;border:1.5px solid color-mix(in srgb,var(--ink-amber,var(--accent)) 55%,transparent)}
.hctx-dots .td-d.on,.hctx-dots .td-d.done{background:var(--ink-amber,var(--accent));border-color:var(--ink-amber,var(--accent))}
/* ASSIST zone — labeled + prominent. Espresso Enter = primary ink as bg + surface as text:
   near-black-on-cream in the notebook theme, high-contrast in dark too. The one standout submit. */
.hero-assist{margin-top:1.125rem}
/* COLLAPSED BY DEFAULT (work order Concept A): a single low-emphasis teaser row; the panel (input +
   Enter + undo/redo/v1) is hidden until expanded. CSS-only — no animation library. */
.ha-toggle{display:flex;align-items:center;gap:0.625rem;width:100%;text-align:left;background:transparent;
  border:1px dashed var(--line);border-radius:12px;padding:0.8125rem 1rem;cursor:pointer;color:var(--muted);font:inherit}
.ha-toggle:hover,.hero-assist.open .ha-toggle{border-color:var(--accent);color:var(--txt)}
.ha-ico{font-size:0.9375rem;line-height:1}
.ha-tease{font-size:0.875rem;font-weight:600}
.ha-chev{margin-left:auto;color:var(--muted);transition:transform .18s ease}
.hero-assist.open .ha-chev{transform:rotate(180deg)}
/* ASSIST OPEN BY DEFAULT (Ken 2026-06-30: no dropdown) inside a SUBTLE CARD (faintly darker than the
   page, not just a border — Ken refinement). Header = label + pill; input/Enter/undo-redo below. */
.hero-assist{margin-top:1.125rem;background:color-mix(in srgb,var(--txt) 3%,transparent);
  border:1px solid color-mix(in srgb,var(--txt) 6%,transparent);border-radius:14px;padding:1rem 1.125rem}
/* ALWAYS AVAILABLE (Ken 2026-07-03 "The prompt is missing on the hero. I always want it
   available" — SUPERSEDES the 07-01 hidden-until-a-verb-press pass): the per-step prompt box
   (chat / adjust / verb-interview thread) shows on EVERY hero. The When? chips stay off. */
.cs-when{display:none!important}
/* smaller + lighter pill (Ken refinement: must not compete with the actions) */
.ha-pill{font-size:0.65625rem;font-weight:600;color:color-mix(in srgb,var(--accent) 70%,var(--muted));white-space:nowrap;
  background:color-mix(in srgb,var(--accent) 8%,transparent);border-radius:999px;padding:0.125rem 0.5rem}
.ha-head{display:flex;align-items:center;gap:0.625rem;margin:0 0 0.75rem;color:var(--muted)}
.ha-head .ha-pill{margin-left:auto}
.ha-label{font-size:0.9375rem;font-weight:700;color:var(--txt)}
.ha-enter{background:var(--txt);color:var(--surface);border:none;border-radius:9px;padding:0 1.125rem;
  font-weight:700;white-space:nowrap;cursor:pointer}
.ha-enter:hover{filter:brightness(1.12)}
.ha-enter:active{transform:translateY(1px)}
.ha-enter[disabled]{opacity:.4;cursor:default}
/* Enter goes GREEN once the box has content (Ken refinement) — set by JS toggling .ready */
.ha-enter.ready{background:var(--done);color:#fff}
/* BREAK SMALLER = ghost blue (Done stays filled green via .cs-done). */
.cs-actions .hero-break{background:transparent;color:var(--accent);
  border:1px solid color-mix(in srgb,var(--accent) 42%,transparent)}
.cs-actions .hero-break:hover{background:color-mix(in srgb,var(--accent) 12%,transparent)}
/* FOOTER RAIL — light top hairline, small left-aligned chips. */
/* FOOTER RAIL — plain icon+text, NOT bordered chips (match the mock): light top hairline, muted items
   left-aligned, the version affordance pushed to the right. */
.hero-foot{display:flex;align-items:center;gap:1.25rem;flex-wrap:wrap;margin-top:1.125rem;padding-top:0.875rem;
  border-top:1px solid var(--line)}
.foot-chip{display:inline-flex;align-items:center;gap:0.4375rem;font-size:0.875rem;color:var(--muted);
  background:transparent;border:none;padding:0.125rem 0;cursor:pointer}
.foot-chip:hover{color:var(--txt)}
.foot-status .stsel{font-size:0.875rem;padding:0.125rem 0;background:transparent;border:none;color:var(--muted);
  max-width:9.375rem;cursor:pointer}
.foot-ver{margin-left:auto;display:inline-flex;align-items:center;gap:0.375rem;font-size:0.8125rem;color:var(--muted);
  background:transparent;border:none;cursor:pointer}
.foot-ver:hover{color:var(--txt)}
/* Share pushed to the far right of the footer (Ken 2026-06-30, where v2 used to sit). */
.hero-foot .foot-share{margin-left:auto}


/* ---- CAGE (Ken 2026-06-25): box the creature in; you can't see inside, but the hatch is
   irresistible. Bars = the obvious gate (swings open on .open). Eyes glow/blink in the dark while
   caged (something's in there — but not WHAT). Latch pulses to beg you to press it. ------------- */
.ferro-cage{ position:fixed; right:1.125rem; top:4.375rem; z-index:40; display:flex; flex-direction:column;
  align-items:center; gap:0.5rem; pointer-events:none; }
.ferro-cage .cage-box{ position:relative; width:6rem; height:6rem; border-radius:10px; overflow:hidden;
  background:#0a0a0c; border:3px solid #3a3026;
  box-shadow:0 8px 22px rgba(0,0,0,.5), inset 0 0 26px rgba(0,0,0,.95); }
.ferro-cage .cage-void{ position:absolute; inset:0;
  background:radial-gradient(ellipse at 50% 62%, #17171d 0%, #050507 72%); }
.ferro-cage .cage-face{ position:absolute; inset:0; width:100%; height:100%;
  transition:opacity .4s; pointer-events:none; }
/* the GATE — the obvious hatch; swings open on .open */
.ferro-cage .cage-bars{ position:absolute; inset:0; transform-origin:left center;
  transition:transform .55s cubic-bezier(.5,-0.25,.3,1.25);
  background:repeating-linear-gradient(90deg, #7a7064 0 4px, transparent 4px 17px);
  border:2px solid #4a3f30; border-radius:6px; box-shadow:inset 0 0 0 1px rgba(0,0,0,.5); }
.ferro-cage.open .cage-bars{ transform:perspective(320px) rotateY(-118deg); }
.ferro-cage.open .cage-face{ opacity:0; }
.ferro-cage .cage-latch{ pointer-events:auto; cursor:pointer; border:0; border-radius:8px;
  padding:0.5rem 0.875rem; font:700 13px/1 ui-sans-serif,system-ui,sans-serif; letter-spacing:.08em;
  color:#1a120a; background:linear-gradient(#ffce5a,#e69a1f);
  box-shadow:0 4px 12px rgba(230,154,31,.5); animation:cagePulse 1.6s infinite; }
.ferro-cage.open .cage-latch{ color:#fff; background:linear-gradient(#7a4a3a,#5a3326);
  box-shadow:0 3px 10px rgba(0,0,0,.4); animation:none; }
/* NO button behind the sign (Ken 2026-06-30): while caged, the OPEN latch is HIDDEN — the "Do not open"
   sign IS the click-to-open temptation. The latch only reappears (as "Send back") once the cage is open. */
.ferro-cage:not(.open) .cage-latch{ display:none; }
.ferro-cage:not(.open) .cage-sign{ pointer-events:auto; cursor:pointer; }
@keyframes cagePulse{ 0%,100%{ transform:scale(1); box-shadow:0 4px 12px rgba(230,154,31,.5); }
  50%{ transform:scale(1.06); box-shadow:0 6px 22px rgba(255,206,90,.9); } }
@media (prefers-reduced-motion:reduce){
  .ferro-cage .cage-latch, .ferro-cage .cage-eyes::before, .ferro-cage .cage-eyes::after{ animation:none; } }

/* CAGE SIGN (Ken 2026-06-25): a red "Do not open" warning tag hung on the cage — which of course
   makes the hatch even harder to resist. Hidden once it's open. */
.ferro-cage .cage-sign{ position:absolute; left:50%; bottom:-0.375rem; z-index:5; transform:translateX(-50%) rotate(-7deg);
  background:#f5ecd6; color:#c01d1d; border:2px solid #c01d1d; border-radius:4px; padding:0.1875rem 0.4375rem;
  font:800 11px/1.04 ui-sans-serif,system-ui,sans-serif; letter-spacing:.05em; text-align:center;
  text-transform:uppercase; box-shadow:0 3px 8px rgba(0,0,0,.45); pointer-events:none;
  transition:opacity .3s; }
.ferro-cage .cage-sign::before{ content:"⚠"; display:block; font-size:0.6875rem; line-height:1; margin-bottom:0.0625rem; }
.ferro-cage.open .cage-sign{ opacity:0; }

/* CAGE ARROW (Ken 2026-06-25): a red hand-drawn arrow looping from the "Do not open" sign down to
   the OPEN button — "don't you dare press this… (it's right here)". Pointer-events off so the latch
   under it stays clickable; fades out once it's open. */
.ferro-cage .cage-arrow{ position:absolute; top:-0.75rem; left:-2.5rem; width:10.625rem; height:11.25rem; z-index:6;
  pointer-events:none; overflow:visible; transition:opacity .3s; }
.ferro-cage .cage-arrow path{ fill:none; stroke:#d83a2a; stroke-width:3.4; stroke-linecap:round;
  stroke-linejoin:round; filter:drop-shadow(0 1px 1px rgba(0,0,0,.35)); }
.ferro-cage.open .cage-arrow{ opacity:0; }
/* CENTER-STAGE WHILE A PLAN IS GENERATING (Ken 2026-06-30 "whenever making a plan he's waiting — put
   him in the center... winking, making faces like he wants to be unleashed"): cage.js adds .center when
   the loader is up. Bigger, dead-center, and the box RATTLES like he's straining to get out. */
/* centered + 50% bigger, nudged DOWN so there's a clear gap below "Looking at your goal…" (Ken 2026-06-30) */
.ferro-cage.center{ right:auto!important; left:50%; top:58%; transform:translate(-50%,-50%) scale(2.25); z-index:60; }
@keyframes cageRattle{ 0%,100%{ transform:translate(0,0) rotate(0) } 20%{ transform:translate(-2px,1px) rotate(-2deg) }
  50%{ transform:translate(1px,-1.5px) rotate(1.5deg) } 80%{ transform:translate(2px,1px) rotate(2deg) } }
.ferro-cage.center .cage-box{ animation:cageRattle .42s ease-in-out infinite; }
@media (prefers-reduced-motion: reduce){ .ferro-cage.center .cage-box{ animation:none; } }

/* ── TOOLBAR + LAUNCH LOGO + APPLE-STYLE SETTINGS (Ken 2026-07-04) ─────────────────────────── */
.nav-arrow{font-size:3.75rem;line-height:1;padding:0.25rem 0.625rem;font-weight:800}   /* 3x (Ken 2026-07-05 'Make the back and forward arrows larger 3x') */
.launchhead{display:flex;align-items:flex-start;gap:1.5rem;min-width:0}   /* logo aligns to the HEADLINE line, not the whole block (Ken 2026-07-07 "center the logo with the slogan") */
.launch-brand{flex:0 0 auto}
.launch-brand .word{font-size:3rem}
.launchhead-txt{min-width:0}
@media (max-width:700px){.launchhead{flex-direction:column;align-items:flex-start;gap:0.5rem}.launch-brand .word{font-size:2.25rem}}
/* Apple-settings look: small-caps section headers, grouped cards, hairline-separated rows,
   label left / control right. All previous control IDs unchanged (save wiring untouched). */
.set-box{max-width:34rem}
.set-box .c{max-height:72vh;overflow-y:auto}
/* CLIPPING FIX (repaint 2026-07-05 — the half-cut rows on Ken's phone): .c is a flex column
   capped by max-height, and .set-group{overflow:hidden} gave every card a min-height of 0 —
   so flex SQUEEZED the cards (clipping first/last rows) instead of letting .c scroll.
   Groups must never shrink; the column scrolls. */
.set-box .c>*{flex:none}
.set-h{font-size:0.71875rem;font-weight:800;letter-spacing:0.08em;text-transform:uppercase;color:var(--muted);margin:1rem 0.25rem 0.375rem}
.set-h:first-child{margin-top:0}
.set-group{background:var(--surface2,rgba(0,0,0,.15));border:1px solid var(--line);border-radius:0.8rem;overflow:hidden}
.set-row{display:flex;align-items:center;justify-content:space-between;gap:0.75rem;padding:0.8rem 1rem;margin:0;width:auto;min-width:0}
/* display:flex would defeat the [hidden] attribute (owner rows leaked into the user view —
   caught by the repaint render pass). The attribute always wins. */
.set-row[hidden],.set-h[hidden],.set-group[hidden]{display:none!important}
.set-row+.set-row{border-top:1px solid color-mix(in srgb,var(--line) 60%,transparent)}
.set-lbl{display:flex;flex-direction:column;gap:0.125rem;font-weight:650;color:var(--txt);min-width:0;flex:1 1 auto}
.set-lbl small{font-weight:500;color:var(--muted);font-size:0.75rem}
/* ONE control language (repaint 2026-07-05): every settings checkbox is a proper SWITCH —
   the old native checkbox + transform:scale(1.25) read as an empty square and clipped on iOS. */
.set-row input[type=checkbox]{appearance:none;-webkit-appearance:none;flex:none;width:2.9rem;height:1.75rem;margin:0;padding:0;
  border-radius:1rem;background:var(--surface2);border:1px solid var(--line2);position:relative;cursor:pointer;transition:background .15s,border-color .15s}
.set-row input[type=checkbox]::after{content:"";position:absolute;top:0.14rem;left:0.14rem;width:1.36rem;height:1.36rem;border-radius:50%;
  background:#fff;box-shadow:0 1px 2px rgba(0,0,0,.28);transition:transform .18s var(--ease,ease)}
.set-row input[type=checkbox]:checked{background:var(--accent,#378add);border-color:transparent}
.set-row input[type=checkbox]:checked::after{transform:translateX(1.12rem)}
/* Inputs FLEX instead of the old rigid 46%+9rem (which shoved past the card edge on phones). */
.set-in{flex:1 1 45%;width:auto!important;min-width:0;max-width:60%;text-overflow:ellipsis}
.set-val{color:var(--muted);font-weight:600;text-align:right;max-width:70%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
#aboutModelsVal{white-space:normal;overflow-wrap:anywhere}   /* Ken wants the EXACT model ids — never ellipsize them */
/* Back up & restore (Ken 2026-07-05): a compact plan list, each with a ⤓ Back up download. */
.set-hint{padding:0.75rem 1rem;color:var(--muted);font-size:0.8125rem}
.backup-list{border-top:1px solid color-mix(in srgb,var(--line) 60%,transparent)}
.backup-row{display:flex;align-items:center;justify-content:space-between;gap:0.75rem;padding:0.625rem 1rem}
.backup-row+.backup-row{border-top:1px solid color-mix(in srgb,var(--line) 45%,transparent)}
.bk-nm{font-weight:600;color:var(--txt);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}
.bk-dl{flex:none;white-space:nowrap}
#restoreBtn{flex:none;cursor:pointer}
a.set-val{text-decoration:none;cursor:pointer}
a.set-val:hover{color:var(--txt)}
/* DANGER ZONE (WO-A2 account deletion): red-edged group + a quiet-but-unmistakable red button. */
#dangerGroup{border-color:color-mix(in srgb,var(--bad,#b53b2d) 55%,var(--line))}
.danger-btn{background:transparent;border:1px solid var(--bad,#b53b2d);color:var(--bad,#b53b2d);border-radius:0.6rem;padding:0.5rem 0.9rem;font-weight:700;cursor:pointer;width:auto}
.danger-btn:hover{background:var(--bad,#b53b2d);color:#fff}
.del-warn{color:var(--bad,#b53b2d);font-weight:650;margin:0 0 0.75rem}
.del-err{color:var(--bad,#b53b2d);min-height:1.2em;font-size:0.85rem;margin-top:0.4rem}
/* Auth small-print (WO-A3): quiet legal links under the sign-in card. */
.auth-legal{margin-top:1rem;font-size:0.75rem;color:var(--muted);text-align:center}
.auth-legal a{color:var(--muted);text-decoration:underline}
.auth-legal a:hover{color:var(--txt)}
/* NATIVE OFFLINE GRACE (WO-A4): opaque full-screen takeover — it must cover a possibly
   blank/error WebView completely, so the background is solid (walnut), never translucent.
   Ink-styled cream card, safe-area aware, fluid rem sizing only. */
.offgrace{position:fixed;inset:0;z-index:12000;display:flex;align-items:center;justify-content:center;
  background:var(--desk,#2a1c11);padding:calc(env(safe-area-inset-top,0px) + 1.5rem) 1.5rem calc(env(safe-area-inset-bottom,0px) + 1.5rem)}
.offgrace[hidden]{display:none}
.off-card{background:var(--surface,#f6f0e1);color:var(--txt,#2c2a23);border-radius:1.1rem;
  padding:2.25rem 2rem;max-width:26rem;width:100%;text-align:center;
  box-shadow:0 1.25rem 3.5rem rgba(0,0,0,.45)}
.off-ico{font-size:2.6rem;line-height:1;margin-bottom:0.6rem}
.off-card h2{margin:0 0 0.5rem;font-size:1.5rem}
.off-card p{margin:0 0 1.4rem;color:var(--muted,#6b6355);line-height:1.5}
.off-card #offlineRetry{min-width:60%;cursor:pointer}
.off-note{margin-top:0.9rem;font-size:0.8rem;color:var(--muted,#6b6355);min-height:1.2em}

/* LOADING LOCKS THE CHROME (Ken 2026-07-05 "when app is loading I want all navigation
   buttons gone… you shouldn't be able to do much while it's loading"): the ferro loader
   (.ferro-load) in the DOM IS the loading signal — while it exists, every topbar control
   and the feedback tab hide. One chokepoint, zero JS to forget.
   HIDE THE WHOLE BAR, not just its contents (Ken 2026-07-07 "if the topbar is ever blank I
   want it GONE — a blank bar looks like something's wrong"): the old rule hid the children
   with visibility:hidden but left an empty cream strip = the "blank topbar". display:none on
   the bar itself removes it cleanly during the wait; it returns the instant loading ends. */
body:has(.ferro-load) .topbar{display:none}
body:has(.ferro-load) .fbtn{visibility:hidden}

/* ACTIVE-PLAN PEEK + SLIDE (Ken 2026-07-07): a right-edge "Resume ›" tab on the launcher (only when an
   active plan exists → hasActivePlan) hinting the swipe/→ into the live plan; + a snappy slide when
   moving Home⟷plan. All proportional; reduced-motion static. */
.plan-peek{position:fixed;right:0;top:50%;transform:translateY(-50%);z-index:15;display:flex;align-items:center;gap:0.35rem;
  padding:0.7rem 0.6rem 0.7rem 0.85rem;border:none;border-radius:0.9rem 0 0 0.9rem;cursor:pointer;
  background:var(--accent,#244a85);color:var(--accent-ink,#f6f0e1);font-weight:800;font-size:0.95rem;
  box-shadow:0 0.4rem 1.1rem rgba(40,26,16,.34);animation:peekNudge 2.6s ease-in-out infinite}
.plan-peek[hidden]{display:none}
.plan-peek .pp-chev{font-size:1.35rem;line-height:1}
.plan-peek:hover{filter:brightness(1.07)}
@keyframes peekNudge{0%,100%{transform:translateY(-50%) translateX(0)}50%{transform:translateY(-50%) translateX(-0.3rem)}}
@keyframes slideScreenR{from{transform:translateX(7%);opacity:.35}to{transform:none;opacity:1}}
@keyframes slideScreenL{from{transform:translateX(-7%);opacity:.35}to{transform:none;opacity:1}}
.screen.slid-r{animation:slideScreenR .28s cubic-bezier(.22,.61,.36,1)}
.screen.slid-l{animation:slideScreenL .28s cubic-bezier(.22,.61,.36,1)}
@media(prefers-reduced-motion:reduce){.plan-peek{animation:none}.screen.slid-r,.screen.slid-l{animation:none}}

/* ═══ GDS PARENT-BRAND FOOTER (Ken 2026-07-10 "footer tool bar at bottom of website with this logo on
   black"). App-wide: the last flex child of .app — always at the bottom, never covers content (screens
   scroll inside .stage). BLACK IS BRAND-FIXED in both themes: the logo art carries its own black field,
   so the bar stays #000 even off-ink (text colors tuned for black — readability first). ═══ */
.gdsbar{flex:none;display:flex;align-items:center;gap:1.25rem;background:#000;
  border-top:1px solid #1d1d1d;min-height:6rem;   /* 2x (Ken 2026-07-10 "twice as large") */
  padding:0.75rem max(1.125rem,env(safe-area-inset-right)) calc(0.75rem + env(safe-area-inset-bottom)) max(1.125rem,env(safe-area-inset-left))}
.gds-logo{height:4.8rem;width:auto;display:block}
.gds-copy{font-size:0.875rem;color:#8d8676;letter-spacing:.02em;white-space:nowrap}
.gds-link{font-size:0.875rem;font-weight:600;color:#b5ac97;text-decoration:none;padding:0.3rem 0.6rem;border-radius:0.375rem}
.gds-link:hover{color:#fff;background:rgba(255,255,255,.09)}
@media(max-width:480px){.gds-copy{display:none}}   /* phones: logo + links only, keep the bar slim */
body.auth-gate .gdsbar{display:none}   /* the sign-in gate stays a clean full screen (matches the topbar rule) */
/* quick-task composer is a ONE-LINE TEXTAREA now (Chrome's password manager never attaches to
   textareas — the autofill-popup fix, Ken 2026-07-10 "make it so these dont think they are entering
   a password"); keep it looking exactly like the old input. */
textarea.capinput{resize:none;overflow:hidden;display:block;white-space:nowrap}

/* GDS logo full-screen view (Ken 2026-07-10 "click the logo → enlarged, entire screen, closable"):
   the shared #imgLightbox goes SOLID BLACK for this art (the piece carries its own black field) and
   the small source is scaled UP to fill the viewport (aspect 539:402 ≈ 1.34). Close = click / ✕ / Esc. */
.imglb:has(img[src*="gds-logo"]){background:#000}
.imglb:has(video#imgLightboxVid:not([hidden])){background:#000}
.imglb img[src*="gds-logo"]{width:min(96vw,calc(92vh*1.9));max-width:96vw;height:auto;border-radius:0;box-shadow:none;cursor:zoom-in}
/* the GDS logo video fills the same box as the still (aspect 1.9), so click-to-play has no jump (Ken 2026-07-10). */
.imglb video#imgLightboxVid{width:min(96vw,calc(92vh*1.9));max-width:96vw;height:auto;border-radius:0;box-shadow:none;background:#000;cursor:zoom-out}
.imglb-x{position:fixed;top:max(0.75rem,env(safe-area-inset-top));right:1.25rem;font-size:2rem;line-height:1;
  color:#e9e1ce;opacity:.8;cursor:pointer;padding:0.5rem;z-index:91}
.imglb-x:hover{opacity:1}

/* CAPPED = MANUAL ONLY (Ken 2026-07-10): every .needs-ai control greys when body.capped; it stays
   hoverable so its title tooltip explains the why + the what-to-do, and a click gets the calm toast
   from capGuard instead of a doomed request. State flips live via the capped-state engine (core.js). */
body.capped .needs-ai{opacity:.4;filter:grayscale(.65);cursor:not-allowed}

/* LIVING TICKET (Ken 2026-07-10): the in-ticket micro-checklist + the field-notes receipt line. */
.cs-check{display:flex;flex-direction:column;gap:0.25rem;margin:0.5rem 0 0.25rem}
.ckx{display:flex;align-items:center;gap:0.5rem;background:transparent;border:none;color:var(--txt);
  padding:0.25rem 0.25rem;text-align:left;font-size:0.9375rem;cursor:pointer;border-radius:0.375rem}
.ckx:hover{background:color-mix(in srgb,var(--accent) 8%,transparent);transform:none;filter:none}
.ckx .ckbox{flex:none;width:1.05rem;height:1.05rem;border:0.125rem solid var(--line2);border-radius:0.25rem;
  display:grid;place-items:center;font-size:0.75rem;line-height:1;color:#fff}
.ckx.done .ckbox{background:var(--good,#4f6e3b);border-color:var(--good,#4f6e3b)}
.ckx.done .cktxt{text-decoration:line-through;opacity:.6}
.cc-receipt{font-size:0.75rem;color:var(--muted);background:transparent;border:none;padding:0.1rem 0.5rem;font-style:italic}

/* PW-MANAGER AUDIT (Ken 2026-07-11 "everywhere there is an edit box that is not a username or password"):
   every non-auth one-line text box is now a <textarea class="oneline"> — Chrome's password manager never
   attaches to textareas (proven on capIn/capedit). core.js delegated handlers keep them single-line. */
textarea.oneline{resize:none;overflow:hidden;display:block;min-height:0}
