/* Astra: daylight blue, midnight blue, a cream object in either room.
   Georgia is deliberate: a native book face, available before any network call.
   Controls use the device's own sans. The engraved number keeps its own voice. */
:root{
  --s0:#e6edef;--s1:#f1f5f6;--s2:#dae4e8;--s3:#cad9e0;
  --edge:#c5d2d8;--edge2:#afc0c9;--edge3:#768e9c;
  --txt1:#203746;--txt2:#3c5464;--txt3:#526978;
  --dim1:#526574;--dim2:#596d7b;--dim3:#647887;--dim:var(--dim1);
  --lime:#d8ed8d;--lime-hi:#e5f4b1;--lime-edge:#c3d87f;--lime-edge2:#8ba345;
  --lime-txt:#435e15;--ink:#28332e;--card:#f6f2e7;--card2:#e9e2d1;
  --card-accent:#415a60;--card-dim:#68675b;--card-edge:#d1cbb9;
  --action:#284c64;--action-text:#fff;--room-glow:rgba(255,255,255,.55);
  --ui:-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;
  --book:Georgia,"Times New Roman",serif;--r:22px;
}
:root[data-theme="dark"]{
  --s0:#142634;--s1:#1b3040;--s2:#253e4e;--s3:#304c5c;
  --edge:#354f60;--edge2:#486372;--edge3:#72909e;
  --txt1:#eef2ee;--txt2:#cad7dc;--txt3:#b1c4cd;
  --dim1:#b0c1ca;--dim2:#a3b9c5;--dim3:#96adbb;--dim:var(--dim1);
  --lime:#d8ed8d;--lime-hi:#e5f4b1;--lime-edge:#c3d87f;--lime-edge2:#a5be67;
  --card:#f6f2e7;--card2:#e9e2d1;--ink:#28332e;--sub:#5f5c50;
  --lime-txt:#d8ed8d;--action:#d8ed8d;--action-text:#243617;
  --room-glow:rgba(160,192,205,.07);
  /* "The room changes. Your cards stay cream." base.css's dark block was turning the card's
     mark and edge olive in Nightfall; the card keeps its Daylight ink here */
  --card-accent:#415a60;--card-dim:#68675b;--card-edge:#d1cbb9;
}
*{box-sizing:border-box}
[hidden]{display:none!important}
html,body{background:var(--s0);color:var(--txt1)}
body.v-auth,body.v-deck,body.v-board,body.v-settings{font-family:var(--ui);background:var(--s0);line-height:1.5}
body.v-deck::before,body.v-board::before,body.v-settings::before{display:none}
button,input,textarea,select{font-family:var(--ui)}
button,a,summary,input,textarea,select{-webkit-tap-highlight-color:transparent}
button{cursor:pointer}
button:disabled{cursor:wait;opacity:.6}
:focus-visible{outline:3px solid var(--sky);outline-offset:4px}
.sr-only{position:absolute;width:1px;height:1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
/* ⛔ `--txt2` IS A COLOUR FOR THE DARK GROUND, and the question sheet is a cream
   card, so "That's enough for now" came out pale grey on cream and was close to
   invisible. It is the way OUT of a run of questions, which makes it the one
   control on that screen somebody has to be able to find.
   ▶ Inside the sheet it takes the card's own ink at reduced weight, which is
   readable without competing with Save. */
#view-deck .done.asking .quiet-link,#view-auth .card .quiet-link{color:var(--txt1);
  opacity:.72}
/* A phone keeps :hover after a tap, so hover looks live behind (hover:hover). */
@media (hover:hover){#view-deck .done.asking .quiet-link:hover,#view-auth .card .quiet-link:hover{opacity:1}}
body .quiet-link{background:none;border:0;color:var(--txt2);text-decoration:underline;text-underline-offset:4px;padding:10px 0;display:inline-flex;align-items:center;min-height:44px;font:14px/1.4 var(--ui)}
:is(#view-deck,#view-board,#view-settings) .astra-header{position:static;display:flex;justify-content:space-between;align-items:center;width:100%;max-width:none;padding:0;margin:0 0 28px;gap:16px}
:is(#view-deck,#view-board,#view-settings) .astra-header h1{font:400 42px/1.15 var(--book);letter-spacing:-1.5px;color:var(--txt1);margin:0}
:is(#view-deck,#view-board,#view-settings) .astra-header p{font:15px/1.5 var(--ui);color:var(--dim1);margin:10px 0 0}
:is(#view-deck,#view-board,#view-settings) .astra-header .mind-link{font:14px/1.2 var(--ui);background:transparent;border:1px solid var(--edge2);border-radius:100px;color:var(--txt1);min-height:46px;padding:10px 18px;flex:none;display:inline-flex;align-items:center}
:is(#view-deck,#view-board,#view-settings) .astra-header .mark{display:none}
body .shellnav{background:var(--s0);border-color:var(--edge);box-sizing:border-box}
body .shellnav a{font:15px/1.3 var(--ui);min-height:52px;color:var(--txt2)}
body .shellnav a.on{background:var(--s2)}
body .shellnav a.on svg{color:var(--txt1)}
body .shellnav::before{font:32px/1 var(--book);padding-bottom:54px}
body .shellnav .bdg{display:none}
body .fbtn{width:44px;height:44px;color:var(--txt2);background:var(--s1);bottom:18px}
body .fsheet .box{padding:28px;box-sizing:border-box}
body .fsheet button{min-height:44px;font-family:var(--ui)}
body .fsheet p{font:14px/1.6 var(--ui)}
body .fsheet textarea{font:16px/1.5 var(--ui)}
@media(min-width:721px){
  body:not(.v-auth){padding:44px 48px 60px 230px!important}
  body .shellnav{width:182px;padding:44px 18px;border-right:1px solid var(--edge)}
  body .shellnav ul{gap:10px}
  body .shellnav a{padding:14px}
}
@media(max-width:720px){
  body:not(.v-auth){padding:24px 20px calc(98px + env(safe-area-inset-bottom))!important}
  body .shellnav{padding:8px 12px calc(8px + env(safe-area-inset-bottom))}
  body .shellnav a{font-size:12px;gap:5px}
  body .fbtn{bottom:calc(88px + env(safe-area-inset-bottom));right:10px}
  :is(#view-deck,#view-board,#view-settings) .astra-header h1{font-size:32px;letter-spacing:-1px}
  :is(#view-deck,#view-board,#view-settings) .astra-header p{font-size:14px}
  :is(#view-deck,#view-board,#view-settings) .astra-header{margin-bottom:24px;gap:12px}
  :is(#view-deck,#view-board,#view-settings) .astra-header .mind-link{font-size:13px;padding:10px 14px}
}
/* Landing: the product in your hand, with room around it. */
body.v-auth.v-land{padding:0!important}
#screen-land{background:var(--s0);height:auto;min-height:100dvh}
:root[data-theme="dark"] #screen-land{background:var(--s0)}
#screen-land #l-sky{opacity:.55;--con-dot:rgba(70,102,118,.4);--con-line:rgba(70,102,118,.2)}
#screen-land .lnav{max-width:1320px;padding:28px 48px}
#screen-land .lmark{font:32px/1 var(--book)}
#screen-land .lmark em{color:inherit}
#screen-land .lnavr .lup{background:var(--s2);border-color:var(--edge2);box-shadow:none;color:var(--txt1)}
#screen-land .lhero{max-width:1220px;grid-template-columns:1.2fr 1fr;grid-template-rows:auto auto;align-content:center;align-items:center;gap:0 70px;padding:32px 48px 60px;flex:1;}
#screen-land .lcopy{order:0;text-align:left;max-width:580px;align-self:end;padding-bottom:28px}
#screen-land h1{font:400 clamp(46px,4.9vw,72px)/1.06 var(--book);letter-spacing:-3px;text-wrap:balance;margin:0 0 28px}
#screen-land .lsub{font:16px/1.8 var(--ui);color:var(--txt2)}
#screen-land .lstack{order:0;grid-column:2;grid-row:1/3;gap:20px}
#screen-land .lcardwrap{width:304px;--r:22px;transform:rotate(3deg)}
#screen-land .lcardwrap .stage{max-width:none}
#screen-land .lcardwrap::before{display:none}
#screen-land .lcardwrap .face,:root[data-theme="dark"] #screen-land .lcardwrap .face{box-shadow:0 2px 2px rgba(0,0,0,.12),0 24px 38px -18px rgba(0,0,0,.4),0 1px 0 #fff inset}
#screen-land .lcta{grid-column:1;align-self:start;align-items:flex-start;gap:16px;margin:0}
#screen-land .lup,#screen-land .lyes{font:500 14px/1.3 var(--ui);background:var(--lime);border-color:var(--lime-edge2);box-shadow:0 2px 0 rgba(255,255,255,.5) inset}
#screen-land .lup.big{font-size:16px;padding:16px 30px;box-shadow:none;min-height:54px}
#screen-land .lup::after{display:none}
#screen-land .lprice{font:13px/1.7 var(--ui);color:var(--dim1)}
#screen-land .lsay{min-height:106px;width:340px;max-width:100%}
#screen-land .lhint{font:13px/1.5 var(--ui);text-transform:none;letter-spacing:0;padding-top:12px}
#screen-land .lwhy{font:12px/1.5 var(--ui)}
#screen-land .lfoot,:root[data-theme="dark"] #screen-land .lfoot{background:transparent;border-top:1px solid var(--edge);padding:28px 48px 22px;gap:22px}
#screen-land .lsteps{max-width:1124px;gap:38px;grid-template-columns:repeat(3,1fr)}
#screen-land .lstep{display:block;font:13px/1.6 var(--ui)}
#screen-land .lstep .n{display:block;font:20px/1.3 var(--book);text-transform:none;letter-spacing:0;color:var(--txt1);margin-bottom:7px}
#screen-land .lfine{font:11px/1.5 var(--ui)}
@media(max-width:879px){
  #screen-land .lnav{padding:18px 22px}
  #screen-land .lhero{display:flex;flex-direction:column;padding:22px 22px 36px;gap:24px}
  #screen-land .lcopy{align-self:center;text-align:center;padding:0;max-width:530px}
  #screen-land h1{font-size:46px;letter-spacing:-1.8px;margin-bottom:18px}
  #screen-land .lsub{font-size:14px;line-height:1.7}
  #screen-land .lcardwrap{width:260px;transform:rotate(2deg)}
  #screen-land .lstack{gap:8px}
  #screen-land .lsay{min-height:52px;width:300px}
  #screen-land .lcta{align-self:center;align-items:center;text-align:center}
  #screen-land .lfoot{padding:26px 24px}
  #screen-land .lsteps{grid-template-columns:1fr;gap:20px;max-width:440px}
  /* 🔴 THE LABEL WAS AN INLINE-BLOCK AND THE SENTENCE FLOWED AROUND IT, so the
     second line wrapped back underneath "Tell it" to the left margin and every
     step read as a ragged L. Found on a phone, 9 September 2026.
     ▶ Two real columns instead: the label holds its own column and the sentence
     holds its own, so a wrap lands under the sentence where it belongs. Baseline
     alignment keeps the serif label sitting on the same line as its first words,
     which is what the inline version was reaching for. */
  #screen-land .lstep{display:grid;grid-template-columns:auto 1fr;
    column-gap:14px;align-items:baseline}
  #screen-land .lstep .n{display:block;font-size:18px;margin:0;white-space:nowrap}
}
@media(min-width:880px) and (max-height:760px){
  #screen-land .lnav{padding-top:20px;padding-bottom:16px}
  #screen-land .lhero{padding-top:12px;padding-bottom:22px}
  #screen-land .lcardwrap{width:250px}
  #screen-land h1{font-size:52px}
  #screen-land .lfoot{padding-top:18px;padding-bottom:16px;gap:14px}
}
/* Today: a card with a resting place. */
body.v-deck{display:block;min-height:100dvh;height:auto;overflow-x:clip}
#view-deck.on{display:flex;align-items:center;flex-direction:column;width:100%;max-width:1120px;margin:0 auto}
#view-deck .astra-header{margin-bottom:0}
#view-deck .when{display:block;font:13px/1.5 var(--ui);color:var(--dim1);margin:8px 0 0;white-space:normal}
#view-deck .ritual-caption{font:16px/1.5 var(--book);color:var(--dim1);text-align:center;margin:24px 0 24px}
#view-deck #stage{width:100%;max-width:320px;min-height:0;padding:0;margin:0 auto}
#view-deck #stage:has(.done){max-width:560px;min-height:0;padding:28px 0}
#view-deck .rule{width:100%;max-width:340px;min-height:68px;margin:28px auto 0}
/* ⛔ THE RULING ROW BELONGS TO THE CARD, NOT TO ONE SCREEN. It was scoped
   #view-deck alone, so the onboarding demo could not use the real buttons and
   invented its own — which is how somebody learned "yes, that's me / not mine"
   and then met "Not mine / Keep it" on their first real card. The card block
   above has been dual-scoped since the landing page shipped; this row was left
   behind. Same treatment: wherever the card object lives, its buttons live. */
#view-deck .swipe, #view-auth .card3d .swipe{display:flex;gap:12px}
#view-deck .swipe button, #view-auth .card3d .swipe button{min-height:54px;font:500 16px/1.2 var(--ui);padding:15px 22px;border-radius:100px}
#view-deck .swipe .no, #view-auth .card3d .swipe .no{background:transparent;border:1px solid var(--edge2);color:var(--txt1)}
#view-deck .swipe .ok, #view-auth .card3d .swipe .ok{background:var(--lime);border:1px solid var(--lime-edge2);color:var(--on-accent)}
#view-deck .swipe button::before, #view-auth .card3d .swipe button::before, #view-deck .swipe button::after, #view-auth .card3d .swipe button::after{display:none}
#view-deck .swipe .ok:hover, #view-auth .card3d .swipe .ok:hover{transform:none;background:var(--lime);color:var(--on-accent);border-color:var(--lime-edge2)}
#view-deck .swipe .no:hover, #view-auth .card3d .swipe .no:hover{transform:none;background:var(--s1);color:var(--txt1);border-color:var(--edge2)}
#view-deck .swipe .ok span, #view-auth .card3d .swipe .ok span{font-size:20px;padding-left:6px}
#view-deck .hint{font:14px/1.5 var(--ui);color:var(--dim1);letter-spacing:0;text-transform:none;padding:8px 0}
#view-deck .keep-receipt{font:20px/1.4 var(--book);color:var(--txt1);text-align:center;padding:12px}
#view-deck .card-thought{text-align:center;margin:9px 0 0}
/* 🔴 "Add a thought" named the mechanic and hid the payoff, and nobody clicked
   it. What somebody types here is the most valuable thing this product collects —
   the brief calls a decline with a reason the most valuable line in the file —
   and the button was asking for it as though it were optional admin.
   ▶ Two lines: what you do, then what it BUYS you. The promise is the half that
   earns the tap, and it is a claim rather than an instruction. */
#view-deck .card-thought summary{display:inline-flex;flex-direction:column;align-items:center;
  gap:3px;min-height:44px;justify-content:center;font:14px/1.5 var(--ui);color:var(--dim1);cursor:pointer}
#view-deck .card-thought summary .tw-pay{font-size:11.5px;line-height:1.4;color:var(--dim2);
  max-width:30ch;text-wrap:balance}
#view-deck .card-thought[open] summary .tw-pay{display:none}
#view-deck .card-thought textarea{width:100%;font:16px/1.5 var(--ui);padding:14px;background:var(--s1);color:var(--txt1);border:1px solid var(--edge2);border-radius:14px;text-align:left}
#view-deck .done{width:100%;max-width:none;max-height:none;overflow:visible;padding:0;text-align:center}
#view-deck .done h2{font:400 40px/1.15 var(--book);letter-spacing:-1px;margin:20px 0}
#view-deck .done p{font:15px/1.7 var(--ui);color:var(--dim1)}
#view-deck .done .big,#view-deck .done .primary{display:block;margin:28px auto 8px;background:var(--action);color:var(--action-text);font:15px/1.4 var(--ui);padding:15px 24px;min-height:52px;border:0;border-radius:100px}
#view-deck .quiet-hour .quiet-link{display:flex;margin:0 auto;justify-content:center}

/* ⭐ THE BETWEEN-TIMES SCREEN. One kept card, one fact, one action. "On your
   mind" lives in the header pill and nowhere else, so it stops being a second
   copy of a button and goes back to being ambient. */
/* the real card object, at rest. Same 5:7, same face, same foil, same shadow as
   the one they ruled on, because it IS the one they ruled on. */
#view-deck .kept-one{position:relative;width:min(300px,74vw);margin:0 auto 16px;
  aspect-ratio:5/7}
#view-deck .kept-one .flip{position:relative;width:100%;height:100%}
#view-deck .kept-one .face.front{position:absolute;inset:0;transform:none;
  backface-visibility:visible}
#view-deck .kept-note{font-size:11px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--dim2);margin:0 0 20px}

/* ⭐ THE AURA. A soft pool of the card's own category colour behind it, breathing
   slowly. It is the only motion on a screen that exists to be still, and it is
   ambient rather than a signal, so nothing depends on seeing it move.
   ⛔ REDUCE MOTION KEEPS THE GLOW AND DROPS THE BREATH. The rule on this site is
   that motion happening TO somebody is suppressed and motion they cause is not,
   and this is the former. Turning it off entirely would take the light away too,
   which is a change to the picture rather than to the movement. */
#view-deck .kept-one .aura{position:absolute;inset:-14% -12%;z-index:-1;
  border-radius:50%;pointer-events:none;
  background:radial-gradient(closest-side,
    color-mix(in srgb, var(--pip,var(--dim2)) 42%, transparent), transparent 72%);
  filter:blur(26px);opacity:.55;animation:auraBreathe 7s ease-in-out infinite}
@keyframes auraBreathe{
  0%,100%{transform:scale(.94);opacity:.42}
  50%    {transform:scale(1.06);opacity:.66}}
html.reduce-motion #view-deck .kept-one .aura{animation:none;
  transform:scale(1);opacity:.55}

#view-deck .quiet-hour .quiet-link{display:block;margin:14px auto 0}
/* the empty deck's card is the deck's own back, smaller and set slightly askew */
#view-deck .seal-back{width:min(210px,54vw);margin:8px auto 30px;transform:rotate(-4deg)}
#view-deck .seal-back .face.back{position:absolute;inset:0;transform:none}
html.reduce-motion #view-deck .seal-back{transform:none}
/* the foil's resting pink composited as a stain outside the flip's 3D context; the seal is
   decorative and never tilts, so it goes */
#view-deck .seal-back .foil{display:none}
#view-deck .hour-seal{width:158px;height:200px;margin:20px auto 32px;display:grid;place-items:center;background:var(--card);color:var(--card-accent);font:38px/1 var(--book);border-radius:22px;border:1px solid var(--card-edge);outline:1px solid var(--card-edge);outline-offset:-12px;box-shadow:5px 6px 0 var(--card2),0 22px 40px -25px #203746;transform:rotate(-6deg)}
#view-deck .done.asking{padding:32px;text-align:left;color:var(--ink)}
#view-deck .done.asking .mq{font:28px/1.3 var(--book);margin:16px 0}
#view-deck .done.asking textarea{background:var(--card);color:var(--ink);font:16px/1.6 var(--ui);min-height:160px}
#view-deck .done.asking .mtier{font:13px/1.5 var(--ui);text-transform:none;letter-spacing:0}
#view-deck .mrow button{min-height:48px;font:14px/1.4 var(--ui)}
#view-deck .scrim{z-index:90}
#view-deck .sheet{z-index:91;max-height:90dvh;overflow-y:auto;background:var(--s1);padding:28px;border-color:var(--edge2)}
#view-deck .sheet .inner{max-width:480px;margin:auto}
#view-deck .sheet h2,#view-deck .mindsheet .mindq{font:30px/1.2 var(--book);color:var(--txt1);margin:10px 0 14px}
#view-deck .sheet .sheet-note,#view-deck .mindsheet .mindhint{font:14px/1.6 var(--ui);color:var(--dim1);margin-bottom:20px}
#view-deck .sheet textarea{font:16px/1.6 var(--ui);background:var(--s0);color:var(--txt1);border:1px solid var(--edge2);border-radius:14px;width:100%;padding:14px}
#view-deck .sheet .row{display:flex;gap:12px;margin-top:20px;flex-wrap:wrap}
#view-deck .sheet button,#view-deck .reads .row button{font:14px/1.4 var(--ui);min-height:48px;padding:12px 20px;border-radius:100px}
#view-deck .reads .row button{background:var(--action);color:var(--action-text);border:1px solid transparent}
#view-deck .reads .row button:hover{color:var(--action-text);border-color:var(--action)}
#view-deck .reads .row .skip{flex:1 1 140px!important;color:var(--txt2)!important}
#view-deck .smaller-choice{display:flex;align-items:center;gap:12px;min-height:48px;margin-top:14px;font:14px/1.5 var(--ui);color:var(--txt2);cursor:pointer}
#view-deck .smaller-choice input{width:22px;height:22px;accent-color:var(--action)}
#view-deck #count-below{display:none!important}
@media(max-width:720px){
  #view-deck .when{display:none}
  /* ⛔ THE TOP CHROME WAS COSTING A THIRD OF THE CARD'S ROOM. On a phone the
     header's h1 is hidden, so the whole bar is a small wordmark and one round
     button, and it was still holding 24px of body padding, a 46px row and 18px
     under the caption before the card could start. His screenshot, 9 September:
     a hand's width of nothing above "A small moment for you". Everything below
     reclaims that space and gives it to the card. */
  body:not(.v-auth){padding-top:10px!important}
  :is(#view-deck,#view-board,#view-settings) .astra-header .mind-link{min-height:38px;padding:8px 13px}
  #view-deck .ritual-caption{margin:6px 0 14px;font-size:15px}
  /* 🔴 svh, NOT dvh, AND THE REASON IS CHROME'S BOTTOM ADDRESS BAR. dvh is the
     viewport as it is RIGHT NOW, so on Chrome for Android with the URL bar at the
     bottom it measures the tall state and the card is sized for space that the
     browser's own chrome is standing in. The rule buttons end up underneath it.
     svh is the SMALL viewport: the height with every bar showing, which is the
     only value that is true in both states. The card is a little smaller on a
     phone and it is always completely visible, which is the trade. */
  #view-deck #stage{max-width:min(304px,calc((100svh - 280px)/1.4));min-width:230px}
  #view-deck .rule{margin-top:26px;max-width:320px}
  #view-deck .done h2{font-size:32px}
  #view-deck .done.asking{padding:22px}
  #view-deck .sheet{padding:22px 22px calc(28px + env(safe-area-inset-bottom))}
}
/* The object: edge, paper, photograph. Same in either room. */
#view-deck .face,.card3d .face,#view-auth .card3d .face{border-radius:22px;background:var(--card)}
#view-deck .front .body,#view-auth .card3d .front .body{padding:20px 22px}
#view-deck .front .wish,#view-auth .card3d .front .wish{font-family:var(--book);font-size:22px;line-height:1.17;letter-spacing:-.5px;color:var(--ink)}
#view-deck .front .why,#view-auth .card3d .front .why{font:13px/1.55 var(--ui);color:var(--sub);margin-top:12px}
#view-deck .front .cat,#view-auth .card3d .front .cat{font:11px/1.4 var(--ui);letter-spacing:0;text-transform:none;color:var(--sub);margin-bottom:10px}
/* 🔴 THE CATEGORY DOT WAS HIDDEN ON EVERY CARD FRONT IN THE PRODUCT. An interface
   pass set display:none here, so no card has ever shown one, and the deck was
   separately looking the colour up against the wrong key so it would have been
   grey even if it had. Two independent reasons the same feature was invisible.
   ⛔ He asked for categories to be visually distinct. A five pixel dot is the
   smallest thing that does it and it is already designed. */
#view-deck .front .cat b,#view-auth .card3d .front .cat b,
#screen-land .front .cat b{display:block;width:5px;height:5px;border-radius:50%;
  background:var(--pip,var(--dim2));flex:none}
#view-deck .face.front,#view-auth .card3d .face.front{overflow:auto;scrollbar-width:none}
#view-deck .face.front::-webkit-scrollbar,#view-auth .card3d .face.front::-webkit-scrollbar{display:none}
#view-deck .shot,#view-auth .card3d .shot{height:44%;object-fit:cover}
.card3d .riser.float{animation:none!important}
.card3d .back .num{color:var(--card-accent)}
.card3d .foil{opacity:.22}
:root.the-eleven #view-deck .ritual-caption{color:var(--lime-txt)}
:root.the-eleven #view-deck .face{outline:2px solid var(--lime);outline-offset:5px}
/* Sign in and six unhurried questions. */
body.v-auth{padding:0 24px!important}
#view-auth .auth{padding:60px 0;min-height:100dvh;display:flex;align-items:center;justify-content:center}
#view-auth .auth.hide{display:none}
#view-auth .authbox{width:100%;max-width:400px}
#view-auth .authbox h1{font:44px/1 var(--book);color:var(--txt1);margin-bottom:22px}
#view-auth .authbox .sub2{font:16px/1.7 var(--ui);color:var(--dim1);margin-bottom:28px}
#view-auth .authbox label{text-transform:none;letter-spacing:0;font:14px/1.4 var(--ui);color:var(--txt2);margin:16px 0 8px}
#view-auth .authbox input{height:50px;font:16px/1.4 var(--ui);background:var(--s1);color:var(--txt1);border:1px solid var(--edge2);border-radius:12px;padding:12px}
#view-auth .authbox button.primary{letter-spacing:0;font:16px/1.4 var(--ui);background:var(--action);color:var(--action-text);min-height:52px;border-radius:100px;margin-top:26px}
#view-auth .authbox .swap{font:14px/1.7 var(--ui)}
#view-auth .swap button{font:14px/1.5 var(--ui);color:var(--txt1);min-height:44px;padding:8px 6px;background:none;border:0;text-decoration:underline;text-underline-offset:4px}
#view-auth .authbox .hint2{font:12px/1.5 var(--ui);color:var(--dim1)}
#view-auth .apple-auth{margin-top:19px}
#view-auth .apple-auth-rule{display:flex;align-items:center;gap:12px;color:var(--dim1);font:13px/1.2 var(--ui);margin-bottom:14px}
#view-auth .apple-auth-rule::before,#view-auth .apple-auth-rule::after{content:"";height:1px;flex:1;background:var(--edge2)}
#view-auth .apple-auth-button{width:100%;min-height:52px;padding:13px 18px;border:1px solid #10110e!important;border-radius:100px!important;background:#10110e!important;color:#fff!important;box-shadow:var(--pill-sh)!important;font:600 16px/1.2 var(--ui)!important}
#view-auth .apple-auth-button span{font-family:-apple-system,BlinkMacSystemFont,sans-serif;font-size:19px;vertical-align:-1px;margin-right:6px}
@media (hover:hover){#view-auth .apple-auth-button:hover{background:#252720!important;box-shadow:var(--pill-sh-up)!important}}
/* ⛔ BLACK ON NIGHTFALL'S BLUE IS 1.22:1. Apple's guidance gives the white button
   style for dark backgrounds, so the dark room gets it. */
:root[data-theme="dark"] #view-auth .apple-auth-button{background:#fff!important;border-color:#fff!important;color:#000!important}
@media (hover:hover){:root[data-theme="dark"] #view-auth .apple-auth-button:hover{background:#f1f1f1!important}}
#view-auth .apple-auth-button:disabled{opacity:.55;transform:none!important}
#view-auth .authbox label .opt{margin-left:6px;font-weight:400;color:var(--dim1)}
/* while signed in but unreachable: only the message and Try again (auth.js unreachable) */
#authform.retrying > :not(#autherr):not(#authretry){display:none}
#view-auth:has(#authform.retrying) :is(#apple-auth,#authswap){display:none}
/* the focus trap (astra.js) focuses a dialog's container so VoiceOver reads it whole; a
   container nobody can tab to never needs a ring, and WebKit drew one on the sheet's edge */
[tabindex="-1"]:focus{outline:none}
/* the sign-in error wore the pre-Astra skin (auth.css: near-black, salmon) on the pale form;
   these are the confirm sheet's two reds, one voice for "that did not go through" */
#view-auth .authbox .err{margin-top:16px;padding:12px 14px;border-radius:14px;
  font:14px/1.5 var(--ui);color:#9a3412;background:var(--s1);border:1px solid var(--edge2)}
:root[data-theme="dark"] #view-auth .authbox .err{color:#f0a37e}
#view-auth #screen-interview{width:100%;padding:0;max-width:760px;margin:auto;min-height:100dvh;background:transparent}
#view-auth #screen-interview::before{display:none}
#view-auth #screen-interview .hd{padding:38px 0;position:static;margin:0;border:0;display:flex;justify-content:space-between;align-items:center}
#view-auth #screen-interview .hd h1{font:32px/1 var(--book);color:var(--txt1)}
#view-auth #screen-interview .sec{font:13px/1.5 var(--ui);letter-spacing:0;text-transform:none;color:var(--dim1)}
#view-auth #screen-interview main{padding:50px 0 60px;display:block;min-height:0}
#view-auth #screen-interview .card{background:none;border:0;box-shadow:none;padding:0;max-width:640px;width:100%;margin:auto;min-height:0}
/* `.q` is also used by the old board-card excerpt component, where it has a
   left rule and inset. That generic rule leaked into every onboarding prompt.
   A question here is simply the question, not a quoted card excerpt. */
#view-auth #screen-interview .q{font:400 38px/1.25 var(--book);letter-spacing:-1px;color:var(--txt1);margin:0 0 20px;padding:0;border:0;font-style:normal}
#view-auth #screen-interview .hint{font:15px/1.7 var(--ui);color:var(--dim1);margin-bottom:24px}
#view-auth #screen-interview textarea{font:18px/1.7 var(--ui);padding:22px;background:var(--s1);color:var(--txt1);border:1px solid var(--edge2);border-radius:18px;min-height:200px;width:100%;resize:vertical}
#view-auth #screen-interview .row{display:flex;align-items:center;gap:10px;margin-top:22px;flex-wrap:wrap}
#view-auth #screen-interview button,#view-auth #screen-interview .row button{font:15px/1.4 var(--ui);padding:14px 24px;min-height:50px;border-radius:100px;background:var(--action);color:var(--action-text);border:0}
#view-auth #screen-interview .row button:hover{background:var(--action);color:var(--action-text)}
#view-auth #screen-interview button.ghost,#view-auth #screen-interview .row button.ghost{background:none;color:var(--txt2)}
#view-auth #screen-interview input.one{font:18px/1.7 var(--ui);padding:16px 22px;min-height:56px;background:var(--s1);color:var(--txt1);border:1px solid var(--edge2);border-radius:18px}
#view-auth #screen-interview textarea:focus,#view-auth #screen-interview input.one:focus{outline:2px solid var(--txt1);outline-offset:3px;border-color:var(--edge2);box-shadow:none}
#view-auth #screen-interview .kbd{font:12px/1.5 var(--ui);color:var(--dim1);margin-top:24px}
#view-auth #screen-interview .finish-mark{font:64px/1 var(--book);color:var(--txt1);margin:0 0 44px}
#view-auth #screen-interview .card.done{text-align:center;padding-top:30px}
#view-auth #screen-interview .arc{max-width:410px;margin:0 auto 32px}
@media(max-width:720px){
  #view-auth #screen-interview .hd{padding:28px 0}
  #view-auth #screen-interview .sec{font-size:12px}
  #view-auth #screen-interview main{padding-top:24px}
  #view-auth #screen-interview .q{font-size:29px;letter-spacing:-.5px}
  #view-auth #screen-interview textarea{font-size:16px;min-height:190px;padding:18px}
  #view-auth #screen-interview .kbd{display:none}
}
/* Motion is an addition to the finished frame, never a requirement for it. */
/* ⛔ THE BLANKET STOPS AT THE CARD. This turned off every animation and every
   transition on the page, which took the turn, the float and the lean with it —
   and those three are not decoration, they are the product. His instruction, twice:
   the flip has to work with reduced motion on, and so do the floating and the
   reacting to the cursor.
   ⭐ THE LINE: motion that happens TO somebody is suppressed. Motion the person
   causes, with their own hand, that stops the moment they stop, is not. */
html.reduce-motion *,html.reduce-motion *::before,html.reduce-motion *::after{animation:none!important;transition:none!important;scroll-behavior:auto!important}
html.reduce-motion .riser.float{animation:float 4.2s ease-in-out infinite!important}
html.reduce-motion .flip{transition:transform 780ms cubic-bezier(.45,.05,.2,1)!important}
html.reduce-motion .tilt{transition:transform 420ms ease-out!important}
html.reduce-motion .tilt.live{transition:transform 90ms ease-out!important}
html.reduce-motion .gone-keep,html.reduce-motion .gone-drop{visibility:hidden}
/* The board is a place to return to, then a collection to browse. */
#view-board .wrap{max-width:1160px;margin:0 auto}
#view-board .board-toolbar{display:flex;align-items:center;justify-content:space-between;gap:20px;margin:0 0 26px}
#view-board .tabs{margin:0;display:flex;gap:4px}
#view-board .tabs button{min-height:44px;padding:10px 20px;font:14px/1.3 var(--ui);letter-spacing:0;border:1px solid transparent;border-radius:100px;color:var(--txt2);background:none}
#view-board .tabs button.on{background:var(--txt1);color:var(--s0);font-weight:500}
#view-board .board-search input{width:210px;min-height:44px;font:14px/1.3 var(--ui);color:var(--txt1);background:var(--s1);border:1px solid var(--edge);border-radius:100px;padding:12px 18px}
#view-board .revisit-card{display:grid;grid-template-columns:40% 1fr;gap:40px;padding:28px;background:var(--s1);border:1px solid var(--edge);border-radius:28px;margin-bottom:32px;align-items:center}
#view-board .revisit-photo{padding:0;border:0;border-radius:18px;overflow:hidden;aspect-ratio:4/3;background:var(--card);transform:rotate(-2deg);box-shadow:0 14px 26px -18px #172d3c}
#view-board .revisit-photo img{display:block;width:100%;height:100%;object-fit:cover;border:9px solid var(--card);border-radius:18px}
#view-board .revisit-label{font:14px/1.5 var(--ui);color:var(--dim1);margin:0 0 14px}
#view-board .revisit-copy h2{font:400 34px/1.16 var(--book);letter-spacing:-.8px;color:var(--txt1);margin-bottom:18px;max-width:24ch;overflow-wrap:anywhere}
#view-board .revisit-why{font:14px/1.6 var(--ui);color:var(--txt2);max-width:52ch}
#view-board blockquote{font:18px/1.5 var(--book);color:var(--txt1);margin:12px 0;overflow-wrap:anywhere}
#view-board blockquote cite{display:block;font:12px/1.5 var(--ui);color:var(--dim1);margin-top:12px;font-style:normal}
#view-board .revisit-actions{display:flex;align-items:center;gap:20px;margin-top:20px;flex-wrap:wrap}
/* the chevron only exists on the phone row; on desktop the two buttons say it */
#view-board .revisit-go{display:none}
#view-board .revisit-actions button:not(.quiet-link){background:var(--action);color:var(--action-text);border:0;min-height:46px;padding:12px 22px;border-radius:100px;font:14px/1.3 var(--ui)}
/* filter left, switch right, and a gap that cannot close */
#view-board .cats{display:flex;align-items:center;justify-content:space-between;
  gap:16px;margin:0 0 20px;padding:0;overflow:visible;flex-wrap:nowrap}
#view-board .cats .category-select{flex:0 1 auto;min-width:0}
#view-board .whytoggle{flex:none;margin-left:auto;display:inline-flex;align-items:center;
  gap:10px;min-height:46px;padding:8px 14px;border-radius:100px;
  background:transparent;border:1px solid var(--edge2);color:var(--txt2);
  font:14px/1.2 var(--ui);cursor:pointer}
#view-board .whytoggle .whylab{white-space:nowrap}
/* ⭐ THE SWITCH IS THE STATE. A track and a knob read as on-or-off at a glance
   in a way no word does, and it is why the label can stop changing. */
#view-board .whytoggle .sw{position:relative;flex:none;width:34px;height:20px;
  border-radius:100px;background:var(--edge2);transition:background .16s}
#view-board .whytoggle .sw i{position:absolute;top:2px;left:2px;width:16px;height:16px;
  border-radius:50%;background:var(--s0);transition:transform .16s;
  box-shadow:0 1px 2px rgba(0,0,0,.25)}
#view-board .whytoggle.on{color:var(--txt1);border-color:var(--edge3,var(--edge2))}
#view-board .whytoggle.on .sw{background:var(--lime)}
#view-board .whytoggle.on .sw i{transform:translateX(14px)}
@media (prefers-reduced-motion: reduce){
  #view-board .whytoggle .sw,#view-board .whytoggle .sw i{transition:none}
}
#view-board .category-select select{min-height:46px;font:14px/1.3 var(--ui);border:1px solid var(--edge2);border-radius:100px;padding:10px 38px 10px 18px;background:var(--s0);color:var(--txt1);max-width:100%}
#view-board .grid{grid-template-columns:repeat(auto-fill,minmax(205px,1fr));grid-auto-rows:auto;gap:24px;align-items:stretch}
#view-board .it{border:1px solid var(--card-edge);border-radius:22px;padding:8px;background:var(--card);color:var(--ink);text-align:left;box-shadow:0 6px 12px -8px #203746;min-width:0}
#view-board .it img{aspect-ratio:5/4;border-radius:15px 15px 4px 4px;background:var(--card2)}
#view-board .it .cap{padding:15px 10px 18px}
#view-board .it .cat{font:11px/1.4 var(--ui);color:var(--sub);letter-spacing:0;text-transform:none;margin-bottom:7px}
#view-board .it .t{font:20px/1.23 var(--book);color:var(--ink);margin:0;text-wrap:pretty;overflow-wrap:anywhere}
#view-board .it .remembered{font:11px/1.4 var(--ui);color:var(--sub);padding:0 10px 12px}
#view-board .it .dnote{font:13px/1.5 var(--ui);color:var(--sub);margin-top:12px}
#view-board .empty{font:16px/1.7 var(--ui);color:var(--dim1);max-width:540px;padding:50px 0}
#view-board .empty h2{font:34px/1.2 var(--book);color:var(--txt1);margin-bottom:20px}
#view-board #sh{z-index:95;padding:24px;align-items:center;background:rgba(10,25,35,.65)}
#view-board .panel{position:relative;background:var(--card);color:var(--ink);border:1px solid var(--card-edge);border-radius:22px;max-width:540px;padding:0;max-height:calc(100dvh - 48px);overflow-y:auto;box-shadow:0 35px 100px -30px #0c1924}
#view-board .panel-photo{display:block;width:100%;height:220px;object-fit:cover}
#view-board .panel-reading{padding:28px}
#view-board .panel-close{position:absolute;top:12px;right:12px;width:44px;height:44px;border-radius:50%;border:1px solid var(--card-edge);background:var(--card);color:var(--ink);font:24px/1 var(--ui);z-index:2}
#view-board .panel .card-category{font:12px/1.4 var(--ui);color:var(--sub);margin-bottom:12px}
#view-board .panel h3{font:30px/1.2 var(--book);letter-spacing:-.5px;color:var(--ink);margin-bottom:18px}
#view-board .panel .why{font:15px/1.7 var(--ui);color:var(--sub);margin-bottom:24px;overflow-wrap:anywhere}
#view-board .panel .say{border:0;margin:24px 0;padding:0}
#view-board .panel .saylab{display:block;font:15px/1.4 var(--ui);color:var(--ink);text-transform:none;letter-spacing:0;margin-bottom:10px}
#view-board .panel textarea{font:16px/1.5 var(--ui);background:var(--card);color:var(--ink);border:1px solid var(--card-edge);border-radius:12px;padding:14px;width:100%;resize:vertical}
#view-board .panel .csave{min-height:46px;font:14px/1.4 var(--ui);background:#284c64;color:white;border:0;border-radius:100px;padding:12px 20px;margin-top:12px}
#view-board .panel .save-note{font:13px/1.5 var(--ui);color:var(--sub);margin-top:10px}
#view-board .panel .your-words{background:var(--card2);border-radius:12px;padding:18px;font:18px/1.5 var(--book);color:var(--ink)}
#view-board .panel .your-words cite{color:var(--sub)}
#view-board .panel .card-more{border-top:1px solid var(--card-edge);border-bottom:1px solid var(--card-edge);padding:5px 0}
#view-board .panel summary{font:14px/1.5 var(--ui);color:var(--sub);min-height:44px;display:flex;align-items:center;cursor:pointer}
#view-board .panel summary::after{content:'+';margin-left:auto}
#view-board .panel details[open] summary::after{content:'−'}
#view-board .panel .opts{display:flex;flex-direction:column;gap:6px;margin-bottom:12px}
#view-board .panel .opts button{min-height:44px;padding:12px;border:1px solid var(--card-edge);border-radius:10px;background:var(--card2);color:var(--ink);font:14px/1.3 var(--ui);text-align:left}
#view-board .panel .opts b{font:14px/1.3 var(--ui);color:var(--ink)}
#view-board .panel .lab{font:14px/1.5 var(--ui);letter-spacing:0;text-transform:none;color:var(--sub);margin:24px 0 12px}
#view-board .panel .nearbit{border-color:var(--card-edge);min-width:115px}
#view-board .panel .nearttl{font:14px/1.3 var(--book);color:var(--ink);padding:10px}
#view-board .panel .card-actions{display:flex;gap:12px;flex-wrap:wrap;margin-top:20px}
#view-board .panel .card-actions button,#view-board .panel .proof,#view-board .panel .sayline,#view-board .panel .closebtn{min-height:44px;font:14px/1.5 var(--ui);background:none;border:0;color:var(--sub);padding:10px 0;text-decoration:underline;text-underline-offset:4px}
@media(max-width:720px){
  #view-board .board-toolbar{gap:10px;flex-wrap:wrap;margin-bottom:20px}
  #view-board .board-search{flex:1;min-width:110px}
  #view-board .board-search input{width:100%;padding-left:14px}
  #view-board .tabs button{padding:10px 12px;font-size:13px}
  /* 🔴 THE PANEL STOPS BEING TWO COLUMNS ON A PHONE. His call, 8 September:
     "on mobile the top modal is all wrong, have the picture span across the top
     and have all the text make the full width."
     ⛔ It was a 94px photo column beside a text column, which is the desktop
     layout with the numbers turned down: the photograph became a stamp too small
     to be the thing anybody kept, and the title, which is a whole sentence, was
     left wrapping to seven lines in what was left. A two-column grid on a 360px
     screen is not a layout, it is two things in each other's way.
     ⭐ One column. The photograph across the top at the card's own 5/7, the words
     underneath at full width, and the two actions on one line the way they sit on
     desktop, because they are one choice and not two. */
  /* 🔴 ON A PHONE THIS IS A ROW, NOT A PANEL. ~470px of interstitial became 64px
     of prompt. The `why`, the quote and the two buttons are all still reachable:
     they are in the card panel, one tap away, which is where somebody who wants
     to read the thing is going anyway. Hiding them here is not hiding them. */
  #view-board .revisit-card{display:flex;align-items:center;gap:12px;
    padding:8px 12px 8px 8px;border-radius:16px;margin-bottom:18px;
    /* the whole row is one control, so it says so under a finger */
    cursor:pointer;-webkit-tap-highlight-color:transparent}
  #view-board .revisit-card:active{background:var(--s2)}
  #view-board .revisit-photo{width:48px;height:48px;flex:none;aspect-ratio:auto;
    border-radius:12px;transform:none;box-shadow:none;margin:0}
  #view-board .revisit-photo img{border-width:0;border-radius:12px}
  #view-board .revisit-copy{min-width:0;flex:1 1 auto}
  #view-board .revisit-label{font:12px/1.3 var(--ui);margin:0 0 2px}
  /* one line, cut with an ellipsis. A title is a whole sentence and this is a
     prompt to open it, not the place to read it. */
  #view-board .revisit-copy h2{font:400 16px/1.3 var(--book);letter-spacing:-.2px;
    margin:0;max-width:none;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  #view-board .revisit-why,
  #view-board .revisit-copy blockquote,
  #view-board .revisit-actions{display:none}
  #view-board .revisit-go{flex:none;font-size:22px;line-height:1;color:var(--dim1);
    padding-right:2px}

  /* 🔴 TWO COLUMNS, BECAUSE ONE IS NOT A BOARD. His question, 8 September: "how
     does this look when a user has hundreds of cards? You want them to infinitely
     scroll cards that are a full viewport tall per piece? Terrible."
     ⛔ `minmax(184px,1fr)` needs 381px to fit two, and a 390px phone has 350px
     after its padding, so the board has ALWAYS been a single column of full-width
     cards on a phone. With the reason showing that is about one screen per card.
     ⭐ Two columns and the reason off by default turns a hundred cards from a
     hundred screens into about ten. */
  #view-board .grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}
  #view-board .it .cap{padding:8px 9px 10px}
  /* 🔴 THE FULL TITLE, ALWAYS. THE PICTURE GIVES UP THE ROOM. His call, 8
     September: "you can't even see the full titles of the cards. Absolutely not.
     The full title must be visible. Why not make the pictures smaller?"
     ⛔ I clamped the title to two lines to get the board from 71 screens to 16,
     and that was the wrong thing to spend. A card is its sentence: "Epson V600 to
     scan your…" is not a shorter version of the want, it is a different and
     useless one, and a board you cannot read is not worth the scrolling it saves.
     ⭐ The photograph is what gives up the height instead. 5:4 on a 168px tile is
     134px of picture; 16:10 is 105. That is most of the two extra lines back, and
     the picture is still doing its job, which is to be recognised rather than
     looked at. */
  #view-board .it img,#view-board .it .noimg{aspect-ratio:16/10}
  #view-board .it .t{font-size:12.5px;line-height:1.3}
  #view-board .it .cat{font-size:7px}
  #view-board blockquote{font-size:15px}
  #view-board .grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:14px}
  #view-board .it{padding:5px;border-radius:18px}
  #view-board .it img{border-radius:13px 13px 4px 4px;aspect-ratio:1}
  #view-board .it .cap{padding:12px 7px 15px}
  #view-board .it .t{font-size:17px}
  #view-board .it .cat{font-size:10px}
  #view-board #sh{padding:14px 10px;align-items:center}
  #view-board .panel{max-height:calc(100dvh - 28px);border-radius:22px}
  #view-board .panel-photo{height:180px}
  #view-board .panel-reading{padding:22px}
  #view-board .panel h3{font-size:27px}
}
/* You: appearance first. No configuration stands between a person and a card. */
#view-settings .wrap{max-width:700px;margin:0 auto}
#view-settings .astra-header{margin-bottom:34px}
#view-settings section{margin-bottom:28px}
#view-settings h2{font:20px/1.4 var(--book);text-transform:none;letter-spacing:0;color:var(--txt1);margin-bottom:10px}
#view-settings h2 i{display:none}
#view-settings .note,#view-settings .danger{font:14px/1.7 var(--ui);color:var(--dim1);margin:8px 0 16px}
#view-settings .themes{gap:16px;margin-top:18px}
#view-settings .tsw{min-height:74px;font:15px/1.5 var(--ui);color:var(--txt2);border:1px solid var(--edge2);padding:14px 20px;border-radius:18px}
#view-settings .tsw.on{border:2px solid var(--txt1);padding:13px 19px;color:var(--txt1)}
/* ⛔ THE CHOSEN ROOM WAS UNREADABLE IN NIGHTFALL. The primary tier paints a chosen
   chip lime, and this rule's --txt1 is near-white in the dark room, so "Nightfall"
   read white on lime. On lime the label takes lime's own ink, in either room. */
:root[data-theme="dark"] #view-settings .tsw.on{color:var(--on-accent,var(--ink))}
#view-settings .sw{width:34px;height:42px;border-radius:7px;transform:rotate(-7deg);border:4px solid var(--card);box-shadow:2px 3px 0 var(--edge);background:#e6edef}
#view-settings .sw-d{background:#142634}
#view-settings .who{font:14px/1.7 var(--ui);color:var(--dim1);overflow-wrap:anywhere}
#view-settings .who b{font-weight:500;color:var(--txt1)}
#view-settings .plan{display:none}
#view-settings .preferences{border-top:1px solid var(--edge2);border-bottom:1px solid var(--edge2);margin-bottom:28px}
#view-settings .preferences summary{font:20px/1.4 var(--book);padding:20px 0;cursor:pointer;min-height:64px;list-style:none;color:var(--txt1)}
#view-settings .preferences summary span{display:block;font:13px/1.5 var(--ui);color:var(--dim1);margin-top:4px}
#view-settings .preferences summary::after{content:'+';float:right;margin-top:-32px;font:24px/1 var(--ui)}
#view-settings .preferences[open] summary::after{content:'−'}
#view-settings .preferences section{padding:12px 0}
#view-settings .pip{width:52px;height:48px;min-width:44px;font:15px/1.4 var(--ui);color:var(--txt1);border:1px solid var(--edge2);border-radius:12px}
#view-settings .pip.on{background:var(--txt1);color:var(--s0);border-color:var(--txt1)}
#view-settings .cat{font:14px/1.4 var(--ui);padding:0 0 0 14px;border:1px solid var(--edge2);min-height:46px;gap:2px}
#view-settings .cat button{width:44px;height:44px;font-size:20px;color:var(--txt2)}
#view-settings .addrow input{font:16px/1.4 var(--ui);min-height:48px;min-width:0;padding:12px 18px}
#view-settings .addrow button{min-height:48px;font:14px/1.4 var(--ui)}
#view-settings .plan-price{font:34px/1.2 var(--book);color:var(--txt1)}
#view-settings .plan-price span{font:14px/1.4 var(--ui);color:var(--dim1)}
#view-settings .signout{min-height:46px;padding:12px 24px;font:14px/1.4 var(--ui);color:var(--txt1);border-color:var(--edge2)}
#view-settings .grp button{min-width:44px;min-height:44px}
#view-settings .grp .note{font-size:13px}

/* Final browser pass: retain the theme on inherited controls and paper forms. */
#view-auth .authbox button.primary:hover{background:var(--action);color:var(--action-text)}
#view-auth #screen-interview .big-btn{font:15px/1.4 var(--ui);letter-spacing:0;background:var(--action);color:var(--action-text);min-height:50px;padding:14px 24px}
#view-auth #screen-interview .card.done .q{border:0;padding-left:0}
#view-deck .done.asking .mrow button{background:#284c64;color:#fff;border:1px solid #284c64;font:14px/1.4 var(--ui);letter-spacing:0;box-shadow:none;min-height:48px}
#view-deck .done.asking .mrow button::after{display:none}
#view-deck .done.asking .mrow .ghostb{background:transparent;color:var(--ink);border-color:var(--card-edge)}
#view-board .it.done .cat{color:var(--sub)}
/* A landing sample must show its whole reason at phone size. */
#view-auth .card3d .front .cat{border:0;border-radius:0;padding:0;background:none}
@media(max-width:879px){
  #view-auth .card3d .shot{height:36%;flex-shrink:0}
  #view-auth .card3d .front .why{padding-top:0}
  #view-auth .card3d .front .wish{margin-top:0}
}

/* the three shapes a correction takes, marked so they are readable at a glance
   rather than buried in a sentence somebody is skimming past */
#view-deck .sheet .sheet-note b{font-weight:600;color:var(--txt1)}

/* ═══ THE CONTROL SYSTEM ══════════════════════════════════════════════════════
 *
 * 🔴 168 BUTTON RULES ACROSS SEVEN STYLESHEETS, 54 FILLED `transparent`, EIGHT
 * TOKENS DOING THE JOB OF "PRIMARY". No system was ever agreed, so every screen
 * invented one. His words: "every pill that has the same fill colour as the
 * background looks SO BAD. SO DULL."
 *
 * ⛔ THE FIRST ATTEMPT AT THIS WAS A LIST OF SELECTORS AND IT WAS THE WRONG SHAPE.
 * A list misses whatever is not on it, and it missed: the feedback sheet, which
 * lives on `body` rather than inside a view, and the sign-out button, and half the
 * pills in settings. A list also matches things that are not controls, and it did:
 * `.danger` is a paragraph and it came out with a shadow.
 * ▶ SO IT IS A BLANKET WITH NAMED EXCEPTIONS. Every button and every select on the
 * site, wherever it is mounted, and a short list of things that are not pills:
 * the card itself, a board tile, an image button, the X inside a chip, and the
 * quiet tier which has no box by definition.
 *
 * THREE TIERS, AND THERE IS NO FOURTH:
 *   1 PRIMARY    lime, dark ink, a shadow that lifts it. One per screen.
 *   2 SECONDARY  a real surface, plus the same shadow at lower weight.
 *   3 QUIET      no box, underline only. Exits and afterthoughts.
 *
 * ⭐ THE RULE UNDER ALL OF IT: no control is ever the fill of its own ground, and
 * every control that has a box has a shadow. A shadow is what makes a pill an
 * object rather than a shape drawn on the page.
 * ⭐ AND EVERY ONE OF THEM MOVES ON HOVER. Raise, never recolour: a colour change
 * on hover reads as a state change, which is a lie. Under reduced motion the lift
 * is dropped and only the shadow deepens.
 */
:root{
  --pill2:var(--s1);
  --pill-sh:0 2px 4px rgba(32,55,70,.1),0 8px 18px -10px rgba(32,55,70,.24);
  --pill-sh-up:0 3px 8px rgba(32,55,70,.15),0 15px 28px -10px rgba(32,55,70,.32);
  --pill-sh-lime:0 2px 5px rgba(12,26,34,.18),0 9px 20px -8px rgba(12,26,34,.36);
  --pill-sh-lime-up:0 4px 9px rgba(12,26,34,.22),0 16px 30px -10px rgba(12,26,34,.44);
}
:root:not([data-theme="light"]){ @media (prefers-color-scheme: dark){
  --pill2:var(--s2);
  --pill-sh:0 2px 5px rgba(0,0,0,.34),0 9px 20px -10px rgba(0,0,0,.55);
  --pill-sh-up:0 4px 9px rgba(0,0,0,.4),0 16px 30px -10px rgba(0,0,0,.66);
}}
:root[data-theme="dark"]{
  --pill2:var(--s2);
  --pill-sh:0 2px 5px rgba(0,0,0,.34),0 9px 20px -10px rgba(0,0,0,.55);
  --pill-sh-up:0 4px 9px rgba(0,0,0,.4),0 16px 30px -10px rgba(0,0,0,.66);
}

/* the things that are not pills. everything else is. */
/* ⛔ THE SHADOW AND THE MOVEMENT ARE FORCED, THE COLOURS ARE NOT. Dozens of older
   rules are more specific than this layer and several set `box-shadow:none` or no
   transition, which is how "Sit with this" and "Save your thought" came out flat
   after this shipped. Those two properties ARE the system, so they win here; fill
   and border stay in the cascade, so a deliberate variant keeps its colour. */
body button:not(.quiet-link,.it,.riser,.revisit-photo,.back,.cat button,
                .shellnav a,.lin,.lup),
body select{
  background:var(--pill2);
  border:1px solid var(--edge2);
  color:var(--txt1);
  box-shadow:var(--pill-sh)!important;
  transition:transform .16s cubic-bezier(.2,.7,.3,1),box-shadow .16s,
             border-color .16s!important;
}
body button:not(.quiet-link,.it,.riser,.revisit-photo,.back,.cat button,
                .shellnav a,.lin,.lup):hover,
body select:hover{
  transform:translateY(-1px)!important;
  box-shadow:var(--pill-sh-up)!important;
}
body button:not(.quiet-link,.it,.riser,.revisit-photo,.back):active{
  transform:translateY(0);box-shadow:var(--pill-sh)}

/* ── 1 · PRIMARY, reasserted so a lime control keeps its fill. */
body :is(button.ok,button.big,button.big-btn,button.primary,button#mindgo,
         button#fbsend,button.send,button#fgo,button.go,
         button.b:not(.ghost):not(.signout),
         button.on,.dial button.on,.cats .cat.on,.kinds button.on){
  background:var(--lime);
  border:1px solid var(--lime-edge2);
  color:var(--on-accent,var(--ink));
  box-shadow:var(--pill-sh-lime)!important;
}
body :is(button.ok,button.big,button.big-btn,button.primary,button#mindgo,
         button#fbsend,button.send,button#fgo,button.go,
         button.b:not(.ghost):not(.signout),
         button.on,.dial button.on,.cats .cat.on,.kinds button.on,
         .revisit-actions button:not(.quiet-link),.say .csave):hover{
  background:var(--lime-hi);
  box-shadow:var(--pill-sh-lime-up)!important;
  border-color:var(--lime-edge2);
}

/* two lime controls that older, more specific rules were painting a different
   colour: the board's own primary and the save under a comment */
body #view-board .revisit-actions button:not(.quiet-link),
body #view-board .say .csave{
  background:var(--lime);border:1px solid var(--lime-edge2);
  color:var(--on-accent,var(--ink));box-shadow:var(--pill-sh-lime)!important}

/* ── 3 · QUIET. No box, so it must not inherit one from the blanket. */
/* ⛔ THESE ARE UNDERLINED TEXT LINKS, NOT PILLS. "This came true" and "Use my
   photo" came out as bare rectangles with a shadow and no radius, because the
   blanket gave them a box they were never designed to hold. */
body .card-actions button,body .quiet-link,body button.back{
  background:none!important;border-color:transparent!important;
  box-shadow:none!important;
}
body .quiet-link:hover,body .card-actions button:hover{transform:none!important}

/* ⛔ THE X BELONGS TO THE CHIP, NOT TO A TIER. Giving it a surface and a shadow
   made it a second button sitting half outside its own pill. */
#view-settings .cats .cat{display:inline-flex;align-items:center;gap:2px;
  padding:8px 8px 8px 16px;overflow:hidden}
#view-settings .cats .cat button{background:none!important;border:0!important;
  box-shadow:none!important;color:inherit;opacity:.5;min-height:0;
  padding:6px 8px;border-radius:100px;line-height:1;font-size:15px}
@media (hover:hover){#view-settings .cats .cat button:hover{opacity:1;transform:none!important;
  background:color-mix(in srgb,currentColor 12%,transparent)!important}}

/* ⛔ THE CHEVRON IS DRAWN BY THE BROWSER, WHICH IS WHY MOVING THE PADDING DID
   NOTHING. Without `appearance:none` the arrow is a UA glyph pinned to the right
   edge and no padding shifts it. Ours now, so its distance from the edge is ours. */
#view-board .category-select select{
  -webkit-appearance:none;appearance:none;
  padding:10px 42px 10px 20px;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5' fill='none' stroke='%23596d7b' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 18px center;
}
:root:not([data-theme="light"]){ @media (prefers-color-scheme: dark){
  #view-board .category-select select{
    background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5' fill='none' stroke='%23a3b9c5' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E")}
}}
:root[data-theme="dark"] #view-board .category-select select{
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5' fill='none' stroke='%23a3b9c5' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E")}

/* ⛔ AND THE FIELDS. A text input is a control and it was transparent too, so the
   board's search read as an outline of nothing next to its own tabs. Same surface,
   same shadow, and it lifts on focus rather than on hover, because that is the
   moment a field becomes the thing you are using. */
body :is(input[type=text],input[type=search],input[type=email],input[type=password],
         input:not([type]),textarea){
  background:var(--pill2);
  border:1px solid var(--edge2);
  color:var(--txt1);
  box-shadow:var(--pill-sh);
  transition:box-shadow .16s,border-color .16s;
}
body :is(input[type=text],input[type=search],input[type=email],input[type=password],
         input:not([type]),textarea):focus{
  border-color:var(--lime-edge2);
  box-shadow:var(--pill-sh-up),0 0 0 3px color-mix(in srgb,var(--lime) 30%,transparent);
  outline:none;
}

@media (prefers-reduced-motion:reduce){
  /* the lift cannot be seen, so only the depth changes */
  body button:hover,body select:hover{transform:none!important}
}


/* ⛔ NO TINTED BOX AROUND THE COMMENT FIELD. The field already says it is a field,
   and a lime panel around it competes with the card's own photograph on a panel
   whose whole job is to show one card. The label and the input are enough. */
#view-board .panel .say{background:none!important;border:0!important;padding:0!important}


/* ⛔ THE COLON HAS TO CONTRAST WITH WHAT IS BEHIND IT, NOT WITH THE PAGE. Inside a
   lime control it was lime on lime and vanished. It takes the control's own ink
   there, which is the same rule stated from the other side. */
body :is(button.ok,button.big,button.big-btn,button.primary,button#mindgo,
         button#fbsend,button.send,button.b:not(.ghost):not(.signout),
         button.on,.revisit-actions button:not(.quiet-link),.say .csave,
         .rare) .eleven{--colon:#43601a}

/* ═══ THE ONBOARDING DEMO IS EXACTLY ONE SCREEN ══════════════════════════════
 *
 * 🔴 HIS INSTRUCTION, 8 September 2026, doing mobile QA on a fresh sign-up:
 * "onboarding must always fit in the viewport, no scrolling", and "make the text
 * larger above the card, impossible to read".
 *
 * ⛔ WHAT WAS WRONG, MEASURED AT 390x740 ON THE THIRD CARD, TURNED: the page ran
 * 71px past the bottom. The cause is that the card is a FIXED 462px tall on every
 * screen, because `.stage` is capped by WIDTH (330px) and `.slot` derives its
 * height from that width through `aspect-ratio:5/7`. Nothing in the chain has
 * ever looked at how much height there is. So the layout was tuned by taking
 * slack out of the gaps, which buys a few pixels once and loses them again the
 * moment a line wraps, and the last card is the one that carries both the
 * wildcard pill and the closing line.
 *
 * ⭐ SO THE CARD IS SIZED BY THE HEIGHT THAT IS LEFT, not by a width somebody
 * chose. The demo becomes a column of one screen, the labels and the ruling row
 * take what they need, and the card takes the rest and keeps its ratio. It
 * cannot overflow, because there is nothing left for it to overflow with.
 *
 * ⛔ `svh`, NOT `vh` OR `dvh`. `vh` ignores the browser's own toolbars and is
 * why a "fits" measured in a headless browser does not fit on his phone. `dvh`
 * changes as the toolbar hides and would resize the card under his thumb. `svh`
 * is the smallest of the three, so what fits, fits, and it never moves.
 *
 * ⛔ Everything here is inside `:has(.card.demo)`, so the real interview, which
 * SHOULD scroll when an answer is long, is untouched. */
@media (max-width:720px){
  #view-auth #screen-interview:has(.card.demo) .hd{padding:14px 0}
  #view-auth #screen-interview:has(.card.demo) main{
    padding:6px 0 10px;height:calc(100svh - 76px);
    display:flex;flex-direction:column;overflow:hidden}
  #view-auth #screen-interview .card.demo{
    flex:1 1 auto;min-height:0;display:flex;flex-direction:column;
    justify-content:flex-start;padding:0}
  /* 🔴 THE CARD IS CAPPED BY THE HEIGHT THAT IS LEFT, AND THAT IS THE WHOLE FIX.
     ⛔ The first version of this made `.slot` `height:100%` inside a flex stage,
     which is a percentage against a parent whose own height is content-driven:
     it resolved to zero and the card VANISHED. Every viewport then reported
     "fits", because nothing was there to overflow. That is why demo-fits.js
     asserts the card has a real width and not merely that the page does not
     scroll: a checker that can be satisfied by deleting the thing it checks is
     worse than no checker.
     ⭐ So nothing about how the card sizes itself changes. `.slot` keeps
     `width:100%` and `aspect-ratio:5/7` exactly as the deck draws it, and the
     only new thing is a ceiling on the stage's WIDTH derived from the height
     that is going spare. 250px is everything else on the screen at its tallest:
     the header, the two labels, the ruling row with the closing line on card
     three, and a little air at the bottom. ⛔ Measured, not chosen: at 250 the
     third card still scrolled 12px on a 664 and a 600 tall screen.
     🔴 AND THE HOME BAR IS PART OF THE CHROME. `env(safe-area-inset-bottom)`
     is 0 in a headless browser and 34px on his phone, so a clearance measured
     here was 34px of a lie there. Reserving it explicitly makes the local
     measurement honest about his device and costs nothing where there is no
     inset. */
  #view-auth #screen-interview .card.demo .stage{
    flex:0 1 auto;min-height:0;margin:auto;
    max-width:min(330px, calc((100svh - 264px - env(safe-area-inset-bottom, 0px)) * 5 / 7))}
  #view-auth #screen-interview .card.demo #d-say{flex:0 0 auto;margin-top:10px}

  /* ⭐ AND THE TWO LINES ABOVE THE CARD ARE READABLE NOW. 10.5px and 8.5px in a
     tracked uppercase mono is a label on a diagram, not a sentence somebody is
     meant to read on a phone. They are the only words explaining what the three
     cards are for. */
  #view-auth #screen-interview .card.demo .blurb{
    font-size:13.5px;letter-spacing:.01em;margin-bottom:10px;
    padding-bottom:0;border-bottom:0}
  #view-auth #screen-interview .card.demo .dkind{
    font-size:11px;letter-spacing:.14em;margin:0 auto 10px;max-width:none}
  #view-auth #screen-interview .card.demo .dkind .dnum{margin-bottom:4px}
  #view-auth #screen-interview .card.demo .hint{font-size:13px;margin-top:8px!important}
}
/* his three sample cards were the only monospace in the app (JetBrains Mono, never loaded,
   so ui-monospace): the pre-Astra skin. Their words and order stay; only the face joins */
#view-auth #screen-interview .card.demo .blurb{font-family:var(--ui);letter-spacing:0;color:var(--txt2)}
#view-auth #screen-interview .card.demo .dkind{font-family:var(--ui);font-weight:600;letter-spacing:.08em}


/* ═══ THE PHONE HEADER, AND WHAT IT COSTS ════════════════════════════════════
 *
 * 🔴 8 September 2026, from him, doing mobile QA: the ruling buttons were cut in
 * half by the tab bar. "The viewport is not able to fit the card, text, bug
 * button, etc. We really need to rethink this."
 *
 * ⭐ HIS OWN THREE PROPOSALS, AND ALL THREE ARE RIGHT.
 *
 * 1. "Maybe we remove the word Today from the today screen on mobile, it's
 *    already in the tab name." ▶ Yes. It is 32px of the largest type on the
 *    screen saying a word that is already lit up in the tab bar underneath it.
 *
 * 2. "A small 11:11 up top MAYBE." ▶ Yes, and it takes the space `Today` just
 *    gave up, so the branding moves to the top of the page for nothing. This is
 *    the same instruction as his earlier one: the mark in the tab bar "shouldn't
 *    be there, the obvious place is at the top of the page". Both are one move.
 *
 * 3. "'Choose your next card' only gets shown when there are no more cards to
 *    rate. On mobile, only." ▶ Yes. It is an escape hatch, and an escape hatch
 *    does not belong beside the thing you are meant to be looking at.
 *    ⭐ `.done` is already what the deck puts in the stage when there is nothing
 *    left to rule, so this needs no new state to keep in step with anything.
 *
 * ⛔ AND THE ARITHMETIC IS THE REAL FIX, not the trimming. The deck card is
 * sized by WIDTH, exactly like the onboarding demo was, so it never knew how
 * much room it had. Trimming the header buys pixels once; sizing the card from
 * the height that is left means it cannot be cut off again by whatever we put
 * back. Same technique, same reason, and `svh` again so the browser's own bars
 * are counted. */
@media (max-width:720px){
  /* 1 · the page title goes, the mark arrives in its place */
  /* gone from sight, never from VoiceOver: the title is how a screen reader knows
     which tab it is on (axe scan, 11 October) */
  :is(#view-deck,#view-board,#view-settings) .astra-header h1{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
  /* ⛔ SMALLER THAN THE TITLE IT REPLACED, ON PURPOSE. His note: "don't make it
     the same size as Today, that's the reason I took 'choose your next card' out
     of the nav, to free up vertical space." A wordmark is a mark, not a heading,
     and every pixel it takes comes off the card. */
  :is(#view-deck,#view-board,#view-settings) .astra-header .mark{
    display:inline-block;font:400 20px/1 var(--book);color:var(--txt1);
    letter-spacing:-.01em}
  /* with the title gone the header is one short line, so it needs a line's room */
  :is(#view-deck,#view-board,#view-settings) .astra-header{margin-bottom:14px}
  /* 2 · and it leaves the tab bar, where it never sat right */
  .shellnav .railmark{display:none}
  /* 3 · the escape hatch, only once there is nothing left to rule */
  #view-deck:not(:has(#stage .done)) .astra-header .mind-link{display:none}

  /* ⛔ THE DECK IS ONE SCREEN. Same shape as the demo: the header, the caption
     and the ruling row take what they need, and the card is capped by the height
     that is left rather than by a width somebody picked.
     ⭐ The `.done` endings are exempt: those screens are meant to be read and a
     long one may legitimately scroll. */
  #view-deck:not(:has(#stage .done)) .stage{
    max-width:min(330px, calc((100svh - 300px - env(safe-area-inset-bottom, 0px)) * 5 / 7));
    margin-left:auto;margin-right:auto;
    /* ⛔ min-width:auto is a flex item's automatic minimum and it resolved to the
       card content's own min-content width, 230px, which quietly overrode the cap
       above on the smallest screen. A max-width that a min-width outranks is not a
       cap. */
    min-width:0}

  /* 🔴 AND THE LAST 29 PIXELS WERE THE BOTTOM PADDING, NOT THE CARD.
     `shell.js` puts `padding-bottom:78px` on the body so scrolling content can
     clear the fixed tab bar, and with the safe-area inset that is 98px on his
     phone. On a screen that is deliberately exactly one screen there is nothing
     to scroll clear of anything: the ruling row already stops above the bar, and
     the padding was pure overflow underneath it. Measured at 360x600: content
     ended at 531, the bar starts at 530, the document was 629 tall.
     ⛔ Only while there are cards. The `.done` endings are read, and reading
     scrolls, so they keep their room. */
  body.v-deck:has(#view-deck.on):not(:has(#stage .done)){
    padding-bottom:0!important;overflow:hidden}
}

/* ═══ THE PANEL PHOTO CARRIES ITS OWN CONTROL ════════════════════════════════
   "Use my photo" was a link at the very bottom of the panel, under both states,
   with an underline and a border the control layer stripped the colour from but
   not the width, which is why it read as a broken box. His call: "it probably
   shouldn't even be a button, it should be some kind of 3 dots on the actual
   image itself." The board's tiles already do exactly that. */
#view-board .panel-shot{position:relative;display:block}
#view-board .shotmenu{position:absolute;top:10px;right:10px;z-index:2;
  width:34px;height:34px;padding:0;border-radius:100px;cursor:pointer;
  display:grid;place-items:center;
  background:rgba(12,12,18,.5);border:0;color:#fff;
  backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px)}
#view-board .shotmenu svg{width:18px;height:18px;fill:currentColor}
@media (hover:hover){#view-board .shotmenu:hover{background:rgba(12,12,18,.68)}}
/* the close button is top right too, so the menu steps aside for it */
#view-board .panel-close ~ .panel-shot .shotmenu{right:52px}

/* ═══ THE PANEL IS A COLUMN, AND ITS ACTIONS CANNOT SCROLL AWAY ══════════════
   His report, 8 September: "EVERYTHING must fit on the modal, it's not obvious
   that you can scroll down to get 2 IMPORTANT BUTTONS, they're completely
   hidden."
   ⛔ The panel was a single scrolling box. On a phone the photograph, a
   three-line title, a four-line reason and a comment field fill the screen, so
   the only two controls that change anything were below the fold with nothing
   indicating they were there. Worse than a hidden control: the last thing
   visible was a full-width lime button, which reads as the end of a form.
   ⭐ Photograph, then a reading area that scrolls, then a footer that does not.
   ⛔ svh again, so the browser's own bars are counted rather than assumed. */
#view-board .panel{display:flex;flex-direction:column;overflow:hidden;
  max-height:calc(100svh - 48px)}
#view-board .panel-shot{flex:none}
#view-board .panel-reading{flex:1 1 auto;min-height:0;overflow-y:auto;
  overscroll-behavior:contain}
#view-board .panel-foot{flex:none;padding:12px 28px calc(16px + env(safe-area-inset-bottom));
  border-top:1px solid var(--card-edge);background:var(--card)}
#view-board .panel-foot .states{margin:0}

/* ⛔ AND THE TWO ROUND CONTROLS STOP SITTING ON TOP OF EACH OTHER. The close
   button is 44px at right:12, so it occupies 12 to 56, and the menu was placed
   at right:52 which is four pixels INSIDE it. They are the same object in two
   roles, so they are the same size, the same shape and the same surface, in one
   row with a gap that is stated rather than arrived at. */
#view-board .panel-close{width:40px;height:40px;font-size:22px;top:12px;right:12px}
/* 40pt circles, 44pt to the thumb: the hit area reaches 2px past each edge (guidelines review) */
#view-board .panel-close::after,#view-board .shotmenu::after{content:"";position:absolute;inset:-2px;border-radius:50%}
#view-board .shotmenu{top:12px;right:60px;width:40px;height:40px;
  background:var(--card);color:var(--ink);border:1px solid var(--card-edge);
  backdrop-filter:none;-webkit-backdrop-filter:none}
#view-board .shotmenu:hover{background:var(--card2)}
#view-board .shotmenu svg{width:20px;height:20px;fill:currentColor}
#view-board .panel-close ~ .panel-shot .shotmenu{right:60px}

@media (max-width:720px){
  /* the photograph gives up height first: it is the one part with no words in it */
  #view-board .panel{max-height:calc(100svh - 24px)}
  #view-board .panel-photo{height:150px}
  #view-board .panel-reading{padding:20px 20px 8px}
  #view-board .panel-foot{padding:10px 20px calc(12px + env(safe-area-inset-bottom))}
  #view-board .panel h3{font-size:24px;line-height:1.18;margin-bottom:12px}
  #view-board .panel .why{font-size:14.5px;line-height:1.6;margin-bottom:16px}
  #view-board .panel .say{margin:16px 0 0}
  #view-board .panel textarea{min-height:78px}
}

@media (max-width:720px){
  /* ⭐ THE NEIGHBOURS STAY, SMALLER. They are 187px of a 578px reading area,
     which is a third of the panel spent on the one part that is not about this
     card. ⛔ But they do not go: the brief calls the graph the only visible
     evidence that the board has a memory, and hiding it behind a disclosure on
     the screen where somebody is deciding whether a want is still theirs is
     hiding the useful half. So: thumbnails without titles, in a row that
     scrolls sideways, with the count in the label. The title is on the card
     they open. 187px becomes about 90. */
  #view-board .panel .lab{margin:14px 0 8px;font-size:13px}
  #view-board .panel .nearbit{flex:0 0 64px;min-width:64px;padding:0;border-radius:10px;
    overflow:hidden;gap:0}
  #view-board .panel .nearbit img,#view-board .panel .nearno{aspect-ratio:1;
    border-radius:10px}
  #view-board .panel .nearttl{display:none}
  #view-board .panel .near{gap:6px;padding:0 0 4px}
}

/* ⛔ AND THE LAST 20px, ON THE SHORT SCREEN ONLY. With Safari's toolbar showing
   a 390x844 phone gives the page about 664, and at that height a long card was
   still 13 to 18px past the bottom after everything above. The photograph gives
   it up, because it is the one part of the panel with no words in it, and only
   on the screens that actually need it: a tall viewport keeps the bigger image. */
@media (max-width:720px) and (max-height:720px){
  #view-board .panel-photo{height:120px}
  #view-board .panel .lab{margin-top:10px}
  #view-board .panel-reading{padding:16px 20px 6px}
}

/* ═══ ABOVE THE BOARD: THREE ROWS, NOT SIX ═══════════════════════════════════
   Measured before touching it, on his own board at 390x844: 345px of chrome
   before the first card, 41% of the screen and 52% once Safari's bar is up.
   Six rows: wordmark, subtitle, tabs+search, revisit, board switcher, filter+
   toggle. His words: "there is SO MUCH SHIT at the top of the page." */

/* the switcher is a switcher, not a heading. It had a border under its name at
   the board's serif size, which reads as a strike through a title. */
#view-board .astra-header .boards{margin:0;flex:none}
#view-board .bpick{font:14px/1.2 var(--ui);color:var(--dim1);gap:6px}
#view-board .bpick .bnm{border-bottom:0;padding-bottom:0}
@media (hover:hover){#view-board .bpick:hover{color:var(--txt1)}
#view-board .bpick:hover .bnm{border-bottom-color:transparent}}

#view-board .board-toolbar{display:flex;align-items:center;gap:12px;margin-bottom:16px}
#view-board .board-toolbar .tabs{margin:0}
#view-board .btools{flex:none;margin-left:auto;width:44px;height:44px;padding:0;
  display:grid;place-items:center;border-radius:100px;cursor:pointer;
  background:transparent;border:1px solid var(--edge2);color:var(--txt2)}
#view-board .btools svg{width:20px;height:20px}
#view-board .btools[aria-expanded="true"]{color:var(--txt1);background:var(--s2)}
#view-board .cats .board-search{flex:1 1 180px;min-width:0}
#view-board .cats .board-search input{width:100%;min-height:44px;border-radius:100px;
  border:1px solid var(--edge2);background:var(--s0);color:var(--txt1);
  padding:10px 18px;font:14px/1.3 var(--ui)}

@media (max-width:720px){
  /* the subtitle is the one line up here that asks for nothing */
  :is(#view-board,#view-deck,#view-settings) .astra-header p{display:none}
  /* ⛔ AND THE TOP RIGHT BELONGS TO THE HELP BUTTON NOW, so the header stops
     pushing anything into it. `space-between` sent the switcher to the right
     edge and it ended up underneath the fixed `?`. Both sit left, and the
     corner is reserved rather than shared. */
  :is(#view-board,#view-deck,#view-settings) .astra-header{
    justify-content:flex-start;padding-right:52px}
  #view-board .astra-header{margin-bottom:14px;gap:10px}
  #view-board .astra-header .boards{margin-left:4px}
  /* ⛔ and the controls are behind the button until they are wanted */
  #view-board .cats{display:none}
  #view-board .cats.open{display:flex;flex-wrap:wrap;gap:10px;margin-bottom:16px}
}
@media (min-width:721px){
  /* on a desktop there is room, and a disclosure that hides nothing worth
     hiding is a click that buys nothing */
  #view-board .btools{display:none}
  #view-board .cats{display:flex}
}
