/* ── Theme ──────────────────────────────────────────────────
   Light is the default and :root carries it. Dark is opt-in via the toggle,
   which stamps [data-theme] on the root -- so a stored choice wins in both
   directions and there is no prefers-color-scheme branch to disagree with it.

   Light is not dark inverted: #5ee39b is unreadable on paper, so the money
   green darkens to #0f7f4f. */
:root{
  --void:#f7f5ef;
  --panel:#fffdf8;
  --panel-2:#fffefb;
  --line:rgba(24,32,28,.10);
  --line-2:rgba(24,32,28,.20);
  --ink:#141a17;
  --ink-2:#33403a;
  --muted:#5c6862;
  --faint:#8a948e;
  --money:#0f7f4f;
  --money-ink:#0b6c42;
  --money-dim:rgba(15,127,79,.10);
  --money-line:rgba(15,127,79,.28);
  --on-money:#ffffff;
  --amber:#a8620d;
  --rust:#b4462a;
  --shot-bg:#eeece5;
  --glow-a:rgba(255,180,84,.26);
  --glow-b:rgba(15,127,79,.13);
  --glow-c:rgba(96,140,255,.11);
  --grain-o:.035;
  --grit:rgba(24,32,28,.12);
  --shadow:0 18px 40px -26px rgba(24,32,28,.35);
  --deck-cast-1:rgba(24,32,28,.16);
  --deck-cast-2:rgba(24,32,28,.40);
  /* Three near-neighbours of the page colour. The backdrop cycles between them
     so the page is never quite the same twice, staying inside one tone family
     -- big enough to notice on a second look, small enough that nothing on top
     of it has to change. */
  --tone-1:#f8f5ee;
  --tone-2:#eef3f0;
  --tone-3:#f3f1f7;
  color-scheme:light;
}
:root[data-theme="dark"]{
  --void:#090c0b;
  --panel:#111614;
  --panel-2:#161d1a;
  --line:rgba(255,255,255,.075);
  --line-2:rgba(255,255,255,.14);
  --ink:#e9efeb;
  --ink-2:#c8d2cb;
  --muted:#8d998f;
  --faint:#626d66;
  --money:#5ee39b;
  --money-ink:#5ee39b;
  --money-dim:rgba(94,227,155,.13);
  --money-line:rgba(94,227,155,.30);
  --on-money:#06120c;
  --amber:#ffb454;
  --rust:#e07a5f;
  --shot-bg:#050807;
  --glow-a:rgba(255,180,84,.15);
  --glow-b:rgba(94,227,155,.12);
  --glow-c:rgba(96,168,255,.09);
  --grain-o:.05;
  --grit:rgba(255,255,255,.18);
  --shadow:0 24px 60px -28px rgba(0,0,0,.9);
  --deck-cast-1:rgba(0,0,0,.55);
  --deck-cast-2:rgba(0,0,0,.85);
  --tone-1:#090c0b;
  --tone-2:#080d11;
  --tone-3:#0d0a0f;
  color-scheme:dark;
}

:root{
  --radius:16px;
  --radius-sm:10px;
  --font:'Inter',system-ui,-apple-system,'Segoe UI',sans-serif;
  --display:'Bricolage Grotesque','Inter',system-ui,sans-serif;
  --mono:ui-monospace,'SF Mono',Menlo,Consolas,monospace;
  --page:760px;
}

*{box-sizing:border-box}
html{scroll-behavior:smooth;scroll-padding-top:88px;overflow-x:clip}
body{
  margin:0;background:var(--void);color:var(--ink);
  font-family:var(--font);font-size:16px;line-height:1.62;
  -webkit-font-smoothing:antialiased;overflow-x:clip;
}
h1,h2,h3,h4{font-family:var(--display);font-weight:700;line-height:1.08;margin:0;letter-spacing:-.025em}
p{margin:0}
a{color:inherit;text-decoration:none}
ul{margin:0;padding:0;list-style:none}
img{max-width:100%;display:block}

/* ── Backdrop ───────────────────────────────────────────────
   Mesh-gradient aurora plus fine grain — the pattern Stripe, Linear and Vercel
   all ship variations of. Four soft blobs pushed toward the corners with one
   accent near the middle, three analogous hues, drifting on long out-of-sync
   loops so the page is never quite still and never asks to be looked at.

   No blur filter and no canvas: radial-gradient is already soft, so this is
   four composited layers moving on transform. It costs a fraction of what a
   blurred-element or per-frame-JS version does on a phone, and it is the whole
   background in ~40 lines. */
.alley{
  position:fixed;inset:0;z-index:0;pointer-events:none;overflow:hidden;
  background-color:var(--tone-1);
  background-image:linear-gradient(180deg,
    color-mix(in srgb,var(--ink) 2%,transparent) 0%,
    transparent 42%,
    color-mix(in srgb,var(--ink) 5%,transparent) 100%);
  animation:tone 30s ease-in-out infinite;
}
/* background-color interpolates cleanly; a gradient between gradients does not.
   So the tone lives on the colour and the shading stays a fixed overlay. */
@keyframes tone{
  0%,100%{background-color:var(--tone-1)}
  34%    {background-color:var(--tone-2)}
  67%    {background-color:var(--tone-3)}
}
.blob{
  position:absolute;border-radius:50%;
  will-change:transform;
  animation:drift var(--dur,58s) ease-in-out infinite alternate;
}
.b1{width:64vw;height:64vw;top:-22vw;right:-14vw;--dur:64s;
  background:radial-gradient(circle at 50% 50%, var(--glow-a), transparent 66%)}
.b2{width:56vw;height:56vw;bottom:-20vw;left:-16vw;--dur:78s;animation-direction:alternate-reverse;
  background:radial-gradient(circle at 50% 50%, var(--glow-b), transparent 66%)}
.b3{width:44vw;height:44vw;top:34%;left:46%;--dur:52s;animation-delay:-19s;
  background:radial-gradient(circle at 50% 50%, var(--glow-c), transparent 68%)}
.b4{width:38vw;height:38vw;bottom:6%;right:8%;--dur:88s;animation-delay:-33s;animation-direction:alternate-reverse;
  background:radial-gradient(circle at 50% 50%, var(--glow-a), transparent 70%)}
@keyframes drift{
  from{transform:translate3d(0,0,0) scale(1)}
  to{transform:translate3d(7vw,-5vh,0) scale(1.16)}
}
/* The grain is what separates a polished gradient from an obvious one. Static
   SVG turbulence: one paint, zero animation cost. */
.grain{
  position:absolute;inset:-50%;opacity:var(--grain-o,.04);
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}
/* A hint of the sparkle, done as one twinkling layer rather than a particle
   system: it reads at the edge of vision and costs a single opacity tween. */
.alley::after{
  content:'';position:absolute;inset:0;
  background-image:
    radial-gradient(1.5px 1.5px at 14% 22%, var(--grit), transparent),
    radial-gradient(1.2px 1.2px at 68% 12%, var(--grit), transparent),
    radial-gradient(1.6px 1.6px at 41% 61%, var(--grit), transparent),
    radial-gradient(1.2px 1.2px at 88% 74%, var(--grit), transparent),
    radial-gradient(1.4px 1.4px at 25% 88%, var(--grit), transparent),
    radial-gradient(1.2px 1.2px at 57% 38%, var(--grit), transparent),
    radial-gradient(1.5px 1.5px at 79% 52%, var(--grit), transparent);
  animation:twinkle 9s ease-in-out infinite alternate;
}
@keyframes twinkle{from{opacity:.28}to{opacity:.72}}
@media (prefers-reduced-motion:reduce){
  .blob,.alley::after,.alley{animation:none}
}

/* ── Nav ────────────────────────────────────────────────── */
.nav{
  position:sticky;top:0;z-index:20;
  display:flex;align-items:center;gap:14px;flex-wrap:nowrap;
  padding:12px max(20px,calc((100vw - var(--page))/2));
  background:color-mix(in srgb, var(--void) 86%, transparent);
  backdrop-filter:blur(14px);
  border-bottom:1px solid var(--line);
  transition:transform .28s cubic-bezier(.4,0,.2,1), opacity .2s;
}
/* Out of the way when you are reading downward, back the moment you reverse --
   and gone entirely while a card is being dragged. */
.nav.nav-hidden{transform:translateY(-102%);opacity:0}
.brand{flex:none}
.brand{display:flex;align-items:center;gap:9px;font-family:var(--display);
  font-size:1.16rem;font-weight:800;letter-spacing:-.03em}
.brand em{font-style:normal;color:var(--money-ink)}
.brand-mark{width:26px;height:26px;flex:none}
.tabs{
  display:flex;gap:4px;flex-wrap:nowrap;margin-left:auto;
  min-width:0;overflow-x:auto;scrollbar-width:none;-webkit-overflow-scrolling:touch;
}
.tabs::-webkit-scrollbar{display:none}
.tab{
  padding:6px 12px;border-radius:999px;font-size:.88rem;font-weight:500;
  color:var(--muted);border:1px solid transparent;white-space:nowrap;
  transition:color .15s, background .15s, border-color .15s;
}
.tab:hover{color:var(--ink);background:color-mix(in srgb, var(--ink) 6%, transparent)}
.tab.on{color:var(--on-money);background:var(--money);border-color:var(--money);font-weight:600}
.tab .count{
  display:inline-block;margin-left:6px;padding:0 6px;border-radius:999px;
  background:color-mix(in srgb, var(--ink) 14%, transparent);
  font-size:.76rem;font-variant-numeric:tabular-nums;
}
.tab.on .count{background:rgba(0,0,0,.22);color:var(--on-money)}

.modes{display:flex;gap:6px;flex:none;margin-left:2px}
.mode{
  flex:none;width:34px;height:34px;border-radius:999px;cursor:pointer;
  border:1px solid var(--line-2);background:transparent;color:var(--muted);
  display:grid;place-items:center;font-size:.95rem;line-height:1;
  transition:color .15s,border-color .15s,transform .3s;
}
.mode:hover{color:var(--amber);border-color:var(--amber)}
.theme:hover{transform:rotate(-18deg)}
.mode svg{width:18px;height:18px}
.mode .m-grid,.mode .m-deck{display:none}
[data-view="grid"] .mode .m-grid,[data-view="deck"] .mode .m-deck{display:block}
[data-view="grid"] .mode .m-list,[data-view="deck"] .mode .m-list{display:none}
[data-view="grid"] [data-view-toggle],
[data-view="deck"] [data-view-toggle]{color:var(--money-ink);border-color:var(--money-line);background:var(--money-dim)}
/* The button shows the action, not the state: on the light default it offers
   the moon, in dark it offers the sun. */
.theme .sun{display:none}
:root[data-theme="dark"] .theme .sun{display:block}
:root[data-theme="dark"] .theme .moon{display:none}

/* ── Layout ─────────────────────────────────────────────── */
.wrap{position:relative;z-index:1;max-width:var(--page);margin:0 auto;padding:48px 20px 20px}

.hero{margin-bottom:30px}
.hero h1{font-size:clamp(2.1rem,6vw,3.15rem);font-weight:800;letter-spacing:-.04em}
.hero .blurb{margin-top:10px;color:var(--muted);font-size:1.04rem;max-width:52ch}
.hero-grave h1{color:var(--rust)}

.stats{display:flex;flex-wrap:wrap;gap:8px;margin-top:20px}
.stats li{
  padding:7px 13px;border:1px solid var(--line);border-radius:999px;
  background:var(--panel);font-size:.83rem;color:var(--muted);
}
.stats b{color:var(--ink);font-family:var(--mono);font-size:.88rem;
  font-variant-numeric:tabular-nums;margin-right:5px}

/* ── Card ───────────────────────────────────────────────── */
.feed{display:flex;flex-direction:column;gap:18px}
.card{
  position:relative;overflow:hidden;
  padding:22px 24px 24px;border:1px solid var(--line);border-radius:var(--radius);
  background:linear-gradient(180deg,var(--panel-2),var(--panel));
  box-shadow:var(--shadow);
  transition:border-color .18s, transform .18s;
}
.card:hover{border-color:var(--line-2);transform:translateY(-2px)}
.card::before{
  content:'';position:absolute;left:0;top:0;bottom:0;width:3px;
  background:linear-gradient(180deg,transparent,var(--line-2) 22%,var(--line-2) 78%,transparent);
}

.kicker{display:flex;flex-wrap:wrap;gap:12px;align-items:baseline;margin-bottom:9px;font-size:.79rem}
.tag{color:var(--faint);letter-spacing:.01em}
.tag::before{content:'#';opacity:.5;margin-right:1px}
.repeat{color:var(--amber);opacity:.85}

.card-top{display:flex;align-items:flex-start;gap:14px}
.card-id{min-width:0;flex:1}
.card h3{font-size:1.42rem;font-weight:800;letter-spacing:-.03em}
.title{border-bottom:1px solid transparent;transition:color .15s,border-color .15s}
.card:hover .title{border-bottom-color:var(--line-2)}
.title:hover{color:var(--money-ink);border-bottom-color:var(--money-line)}
.out{font-size:.62em;font-weight:600;margin-left:5px;color:var(--faint);
  opacity:0;transition:opacity .15s;vertical-align:super}
.card:hover .out{opacity:1}
.solo{
  display:inline-block;vertical-align:middle;margin-left:8px;
  padding:3px 10px;border-radius:999px;border:1px solid var(--line-2);
  font-family:var(--font);font-size:.72rem;font-weight:600;letter-spacing:.01em;
  color:var(--muted);white-space:nowrap;position:relative;top:-2px;
}
.solo-high{color:var(--money-ink);border-color:var(--money-line);background:var(--money-dim)}
.solo-low{color:var(--rust);border-color:color-mix(in srgb,var(--rust) 34%,transparent)}
.by{margin-top:6px;font-size:.85rem;color:var(--faint)}
.by a{color:var(--muted);border-bottom:1px solid transparent}
.by a:hover{color:var(--money-ink);border-color:var(--money-line)}
.dot{opacity:.45;margin:0 2px}

.save{
  flex:none;width:36px;height:36px;border-radius:10px;cursor:pointer;
  border:1px solid var(--line);background:transparent;
  color:var(--faint);font-size:1.05rem;line-height:1;
  display:grid;place-items:center;transition:color .15s,border-color .15s,background .15s;
}
.save:hover{color:var(--amber);border-color:var(--line-2)}
.save .save-on{display:none}
.save[aria-pressed="true"]{color:var(--amber);border-color:color-mix(in srgb,var(--amber) 42%,transparent);
  background:color-mix(in srgb,var(--amber) 12%,transparent)}
.save[aria-pressed="true"] .save-off{display:none}
.save[aria-pressed="true"] .save-on{display:block}

.idea{margin-top:13px;font-size:1.02rem;color:var(--ink-2)}

/* ── Traction ───────────────────────────────────────────── */
.chips{display:flex;flex-wrap:wrap;gap:7px;margin-top:14px}
.chip{
  display:flex;align-items:baseline;gap:6px;padding:5px 11px;border-radius:8px;
  border:1px solid var(--line);background:color-mix(in srgb,var(--ink) 4%,transparent);
  font-size:.82rem;
}
.chip b{font-family:var(--mono);font-size:.87rem;font-variant-numeric:tabular-nums;color:var(--ink)}
.chip span{color:var(--faint)}
.chip-money{border-color:var(--money-line);background:var(--money-dim)}
.chip-money b{color:var(--money-ink)}
.chip-money span{color:color-mix(in srgb,var(--money-ink) 70%,transparent)}

.no-numbers{
  margin-top:15px;padding:6px 12px;border-radius:8px;font-size:.8rem;
  color:var(--faint);border:1px dashed var(--line-2);display:inline-block;
}

.quote{
  margin:13px 0 0;padding:10px 14px;border-left:2px solid var(--line-2);
  background:color-mix(in srgb,var(--ink) 3%,transparent);border-radius:0 8px 8px 0;
  font-size:.89rem;color:var(--muted);font-style:italic;
}
.quote::before{content:'“'}
.quote::after{content:'”'}

/* ── Preview shot ───────────────────────────────────────── */
.shot{
  position:relative;display:block;margin-top:15px;border-radius:var(--radius-sm);
  overflow:hidden;border:1px solid var(--line);background:var(--shot-bg);
  transition:border-color .18s;
}
.shot:hover{border-color:var(--line-2)}
/* Screenshots come in wildly different shapes — one is 900x1950. Cap the height
   and anchor to the top so a tall app screenshot shows its head, not its middle. */
.shot img{width:100%;max-height:420px;object-fit:cover;object-position:top}
.shot-tag{
  position:absolute;right:8px;bottom:8px;padding:3px 9px;border-radius:999px;
  background:rgba(0,0,0,.62);color:#fff;font-size:.72rem;backdrop-filter:blur(6px);
  opacity:0;transition:opacity .18s;
}
.shot:hover .shot-tag{opacity:1}

/* ── Judgement ──────────────────────────────────────────── */
.note{margin-top:17px}
.note h4{
  font-family:var(--font);font-size:.71rem;font-weight:600;letter-spacing:.12em;
  text-transform:uppercase;color:var(--faint);margin-bottom:6px;
}
.note p{font-size:.95rem;color:var(--ink-2)}
/* The adjacent opportunity: same block, but marked, because it answers a
   different question than the paragraph above it. */
.note .next{
  margin-top:11px;padding-left:14px;border-left:2px solid var(--amber);
  color:var(--muted);
}
.note .next::before{
  content:'so: ';color:var(--amber);font-weight:600;
}

/* ── Graveyard ──────────────────────────────────────────── */
.graves{display:flex;flex-direction:column;gap:12px}
.grave{
  padding:20px 22px;border:1px solid var(--line);border-radius:var(--radius);
  background:linear-gradient(180deg,color-mix(in srgb,var(--rust) 6%,transparent),var(--panel));
}
.grave-head{display:flex;align-items:baseline;gap:14px}
.grave h3{font-size:1.16rem;font-weight:700;flex:1;min-width:0}
.seen{flex:none;font-size:.78rem;color:var(--faint);white-space:nowrap}
.seen b{font-family:var(--mono);font-size:1.05rem;color:var(--rust);margin-right:3px}
.grave p{margin-top:9px;font-size:.92rem;color:var(--muted)}
.grave-cta{margin-top:28px;text-align:center;color:var(--muted)}
.grave-cta em{font-style:italic;color:var(--ink)}
.grave-cta a{color:var(--money-ink);border-bottom:1px solid var(--money-line)}

/* ── Patterns ───────────────────────────────────────────── */
.patterns{margin-top:52px;padding-top:34px;border-top:1px solid var(--line)}
.patterns h2{font-size:1.6rem;font-weight:800;letter-spacing:-.03em}
.pattern{margin-top:24px}
.pattern h3{font-size:1.05rem;font-weight:700;color:var(--amber)}
.pattern p{margin-top:7px;color:var(--muted);font-size:.95rem}

/* ── Signup ─────────────────────────────────────────────── */
.signup{
  margin:56px 0 20px;padding:28px;border-radius:var(--radius);
  border:1px solid var(--money-line);
  background:linear-gradient(150deg,var(--money-dim),color-mix(in srgb,var(--ink) 2%,transparent));
}
.signup h2{font-size:1.45rem;font-weight:800;letter-spacing:-.03em}
.signup p{margin-top:7px;color:var(--muted);font-size:.93rem;max-width:48ch}
.signup-form{display:flex;gap:9px;margin-top:16px;flex-wrap:wrap}
.signup-form input{
  flex:1;min-width:220px;padding:12px 15px;border-radius:10px;
  border:1px solid var(--line-2);background:var(--panel);
  color:var(--ink);font-family:var(--font);font-size:.95rem;
}
.signup-form input::placeholder{color:var(--faint)}
.signup-form input:focus{outline:2px solid var(--money-line);outline-offset:1px;border-color:transparent}
.signup-form button{
  padding:12px 22px;border-radius:10px;border:none;cursor:pointer;
  background:var(--money);color:var(--on-money);
  font-family:var(--display);font-size:.95rem;font-weight:700;
  transition:filter .15s,transform .1s;
}
.signup-form button:hover{filter:brightness(1.08)}
.signup-form button:active{transform:translateY(1px)}
.signup-form button[disabled]{opacity:.55;cursor:default}
.signup-msg{margin-top:11px;font-size:.88rem;min-height:1.2em}
.signup-msg.ok{color:var(--money-ink)}
.signup-msg.err{color:var(--rust)}

/* ── Misc ───────────────────────────────────────────────── */
.empty{padding:46px 4px;text-align:center;color:var(--faint)}
.foot{
  position:relative;z-index:1;max-width:var(--page);margin:0 auto;
  padding:30px 20px 60px;border-top:1px solid var(--line);
  color:var(--muted);font-size:.86rem;
}
.foot p + p{margin-top:8px}
.foot .fine{color:var(--faint);font-size:.81rem;max-width:64ch}
.foot a{color:var(--muted);border-bottom:1px solid var(--line-2)}

@media (max-width:640px){
  .wrap{padding-top:32px}
  .nav{gap:10px;padding-top:10px;padding-bottom:10px}
  .brand span{display:none}          /* the mark alone is enough on a phone */
  .card{padding:20px 18px 16px}
  .card h3{font-size:1.24rem}
  .solo{margin-left:0;margin-top:6px;display:block;width:max-content;top:0}
  .shot img{max-height:300px}
}
@media (prefers-reduced-motion:reduce){
  *{transition:none!important;animation:none!important;scroll-behavior:auto!important}
}


/* ── Deck view ──────────────────────────────────────────────
   A presentation of the same cards, not a different page: the nodes, their save
   buttons and the saved counter are shared with the list view. Only position
   and input handling change. */
.deck-stage{display:contents}      /* invisible in list and column views */
.deck-hint,.deck-controls,.deck-done{display:none}

[data-view="deck"] .deck-hint{
  /* Three equal columns, so the count is centred over the deck rather than
     centred between two labels of different lengths. */
  display:grid;grid-template-columns:1fr auto 1fr;align-items:baseline;gap:10px;
  max-width:440px;margin:0 auto 14px;width:100%;
  font-size:.82rem;color:var(--faint);
}
.hint-l{text-align:left}
.hint-r{text-align:right}
.hint-l kbd{margin-left:12px}
.hint-r kbd{margin-right:12px}
.hint-c{white-space:nowrap}
[data-view="deck"] .deck-hint b{color:var(--money-ink);font-family:var(--mono);margin-right:3px}
kbd{
  font-family:var(--mono);font-size:.78em;padding:1px 6px;border-radius:5px;
  border:1px solid var(--line-2);color:var(--muted);
}

/* ── Newspaper (two columns) ────────────────────────────────
   Real multi-column, not a grid: text flows down column one and continues in
   column two, which is what a newspaper actually does and what packs tiles
   without leaving ragged gaps between uneven cards. */
[data-view="grid"] .wrap,
[data-view="grid"] .foot{max-width:1180px}
[data-view="grid"] .feed{
  display:block;
  columns:2;
  column-gap:20px;
}
[data-view="grid"] .card{
  break-inside:avoid;
  -webkit-column-break-inside:avoid;
  margin:0 0 20px;
  display:inline-block;width:100%;   /* Safari needs this to honour the break */
}
[data-view="grid"] .card h3{font-size:1.24rem}
[data-view="grid"] .idea{font-size:.96rem}
[data-view="grid"] .note p{font-size:.91rem}
[data-view="grid"] .shot img{max-height:260px}
@media (max-width:900px){
  [data-view="grid"] .feed{columns:1}
}

/* ── Deck ───────────────────────────────────────────────────
   A swipe card is a poster, not a document. The list card — kicker, title,
   prose, prose — dropped into a fixed box and left to scroll internally is the
   wrong object: it has to read in one glance and hold a consistent silhouette.

   Same DOM. `order` re-stacks it into image / title / numbers / hook. */
[data-view="deck"] .hero,
[data-view="deck"] .patterns,
[data-view="deck"] .signup{display:none}
[data-view="deck"] .deck-stage{
  display:flex;flex-direction:column;justify-content:center;
  min-height:calc(100dvh - 132px);
}
[data-view="deck"] .feed{
  position:relative;
  height:min(74vh,620px);
  max-width:440px;margin:0 auto;width:100%;
}
[data-view="deck"] .card{
  position:absolute;inset:0;margin:0;
  display:flex;flex-direction:column;
  padding:0 20px 0;
  overflow:hidden;
  transform-origin:50% 92%;
  will-change:transform;
  touch-action:pan-y;
  transition:transform .3s cubic-bezier(.25,.8,.35,1),opacity .3s;
}
/* Shadow is capped at the top card. Inheriting var(--shadow) on every card
   meant DEPTH+1 blurred edges at DEPTH+1 different scales, 10px apart, each
   showing through the next one's opacity -- that is the stepped/zigzag edge --
   and each overlap made the result darker, so the pile got muddier the deeper
   it was. One shadow has nothing to compound with, at any DEPTH.
   Cards behind still read as a stack from their offset and scale alone. */
[data-view="deck"] .card{box-shadow:none}
/* Two layers on the one card that casts: a tight contact shadow plus a wide
   soft one. A single large-blur/negative-spread shadow bands visibly on
   low-bit-depth displays; splitting it is what actually reads as smooth. */
[data-view="deck"] .card.deck-top{
  box-shadow:0 3px 8px -4px var(--deck-cast-1), 0 22px 46px -28px var(--deck-cast-2);
}
[data-view="deck"] .card:hover{transform:none}
[data-view="deck"] .card.deck-top{cursor:grab}
[data-view="deck"] .card.swiping{cursor:grabbing}
[data-view="deck"] .card.deck-top:active{cursor:grabbing}
/* The 3px stripe is a list-view affordance. Off for every deck card, so no
   card is missing an edge its neighbour has -- the earlier version reused this
   same pseudo-element for the no-image band, which is exactly why some cards
   had a left edge and some did not. */
[data-view="deck"] .card::before{display:none}

/* Hero image, bled to the card edges, with a shadow under it so the card does
   not look like two unrelated rectangles stacked. */
[data-view="deck"] .shot{
  order:1;flex:none;margin:0 -20px;border:0;border-radius:0;
  height:40%;min-height:140px;z-index:1;
}
[data-view="deck"] .shot img{height:100%;max-height:none;object-position:center top}
/* Inner shadow, inside the image. An inset box-shadow would paint under the
   <img>, so it has to be an overlay. */
[data-view="deck"] .shot::after{
  content:'';position:absolute;inset:0;
  background:linear-gradient(180deg,
    transparent 42%,
    rgba(0,0,0,.30) 72%,
    rgba(0,0,0,.62) 92%,
    rgba(0,0,0,.78));
  pointer-events:none;
}
[data-view="deck"] .shot-tag{display:none}

/* No picture: a tinted band standing in for the screenshot. It is a real
   element rather than a painted-on background because it has to occupy the
   hero slot at exactly the height a real .shot does -- the previous version
   faked it with padding plus background-size and the two numbers drifted, so
   an image-less card sat visibly shorter than the one behind it. Keep the
   geometry below identical to the .shot rule above; that is the whole point
   of this block. */
.shot-none{display:none}
[data-view="deck"] .shot-none{
  display:block;position:relative;
  order:1;flex:none;margin:0 -20px;
  height:40%;min-height:140px;z-index:1;
  background-image:
    radial-gradient(120% 150% at 20% 0%, var(--money-dim), transparent 70%),
    linear-gradient(160deg, color-mix(in srgb,var(--amber) 13%,transparent), transparent 62%),
    linear-gradient(180deg,var(--panel-2),var(--panel));
}
/* The same foot as a real screenshot, softer: the band is flat colour, so it
   needs far less darkening to sit under the text than a photo does. */
[data-view="deck"] .shot-none::after{
  content:'';position:absolute;inset:0;
  background:linear-gradient(180deg,transparent 55%,rgba(0,0,0,.16) 85%,rgba(0,0,0,.26));
  pointer-events:none;
}

[data-view="deck"] .kicker{order:2;flex:none;margin:14px 0 6px}
[data-view="deck"] .card-top{order:3;flex:none;align-items:flex-start}
[data-view="deck"] .card h3{font-size:1.3rem;line-height:1.15}
[data-view="deck"] .chips,
[data-view="deck"] .no-numbers{order:4;flex:none;margin-top:12px}
[data-view="deck"] .idea{order:5;flex:none;margin-top:12px;font-size:.95rem;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
[data-view="deck"] .quote{display:none}
/* Nothing inside a deck card scrolls -- a scroller here competes with the
   swipe for the same gesture. The judgement simply runs off the bottom under
   the fade, and a tap opens the untruncated record. */
[data-view="deck"] .note{
  order:6;flex:1 1 auto;min-height:0;margin-top:12px;overflow:hidden;
}
[data-view="deck"] .note h4{margin-bottom:4px}
[data-view="deck"] .note p{font-size:.9rem}
[data-view="deck"] .note .next{display:none}
[data-view="deck"] .save{position:relative;z-index:3}

/* The fade belongs to the card, pinned to its bottom edge -- not to the
   scrolling text, where it slid up the card as you read it. */
[data-view="deck"] .card::after{
  content:'';position:absolute;left:0;right:0;bottom:0;height:52px;z-index:2;
  background:linear-gradient(180deg,transparent,var(--panel) 82%);
  pointer-events:none;
}

/* Sits behind the stack at all times, so swiping the last card away reveals it
   rather than swapping one panel for another. */
.deck-empty{display:none}
[data-view="deck"] .deck-empty{
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  position:absolute;inset:0;z-index:0;text-align:center;padding:24px;
  color:var(--faint);pointer-events:none;
}
.empty-mark{width:66px;height:66px;color:var(--line-2);margin-bottom:14px}
.empty-big{font-family:var(--display);font-weight:800;letter-spacing:-.03em;
  font-size:1.7rem;color:var(--muted)}
.empty-small{margin-top:6px;font-size:.9rem;max-width:26ch}

/* Stamps live on the deck container: it always exists and never moves, so a
   stamp cannot ride away with the card it labels. */
[data-view="deck"] .feed::before,
[data-view="deck"] .feed::after{
  /* Above every card. Cards top out at 40, and at an equal z-index DOM order
     decides -- which left ::before (TOSS) painting under the top card. */
  position:absolute;top:18px;z-index:50;
  padding:6px 14px;border-radius:10px;font-family:var(--display);
  font-weight:800;font-size:1.02rem;letter-spacing:.06em;
  background:color-mix(in srgb,var(--void) 74%,transparent);
  pointer-events:none;
}
[data-view="deck"] .feed::after{
  content:'KEEP';right:16px;
  color:var(--money-ink);border:2.5px solid var(--money-ink);
  transform:rotate(-11deg) scale(calc(.82 + var(--stash,0) * .18));
  opacity:var(--stash,0);
}
[data-view="deck"] .feed::before{
  content:'TOSS';left:16px;
  color:var(--rust);border:2.5px solid var(--rust);
  transform:rotate(11deg) scale(calc(.82 + var(--pass,0) * .18));
  opacity:var(--pass,0);
}

[data-view="deck"] .deck-controls{
  display:flex;justify-content:center;align-items:center;gap:14px;margin-top:22px;
  /* Above the card cast. Cards top out at z-index 40 and the stamps sit at 50;
     .feed is position:relative with z-index:auto, so none of that is boxed into
     its own stacking context and the buttons have to clear it explicitly. The
     dark-mode shadow reaches ~26px past the card, further than this margin. */
  position:relative;z-index:60;
}
/* One size, one shape, one stroke weight for all three -- the earlier mix of
   two text glyphs and one SVG at a smaller diameter never lined up. Undo is
   held back with colour and a lighter border, not with geometry. */
.dbtn{
  width:56px;height:56px;flex:none;border-radius:999px;cursor:pointer;
  border:1px solid var(--line-2);background:var(--panel);color:var(--muted);
  line-height:1;display:grid;place-items:center;
  font-family:var(--font);font-size:.95rem;
  transition:color .15s,border-color .15s,transform .12s,background .15s;
}
.dbtn svg{width:24px;height:24px;display:block}
.dbtn:hover{transform:translateY(-2px)}
.dbtn:active{transform:translateY(0)}
.dbtn.undo{border-color:var(--line);color:var(--faint)}
.dbtn.undo svg{width:20px;height:20px}
.dbtn.undo:hover{color:var(--muted);border-color:var(--line-2)}
.dbtn.pass:hover{color:var(--rust);border-color:var(--rust)}
.dbtn.stash:hover{color:var(--money-ink);border-color:var(--money-ink);background:var(--money-dim)}
.dbtn.wide{width:auto;height:auto;padding:11px 20px;border-radius:10px;
  font-family:var(--display);font-weight:700;font-size:.92rem}

[data-view="deck"] .deck-done{
  display:flex;flex-direction:column;align-items:center;gap:14px;
  margin-top:26px;color:var(--muted);text-align:center;
}
[data-view="deck"] .deck-done a{color:var(--money-ink);border-bottom:1px solid var(--money-line)}

/* Deck mode is a focused reading mode; the weekly column belongs to the list. */
[data-view="deck"] .patterns{display:none}

@media (max-width:640px){
  [data-view="deck"] .feed{height:min(72vh,560px)}
  [data-view="deck"] .card h3{font-size:1.18rem}
  .dbtn{width:52px;height:52px}
}


/* ── Full record sheet ──────────────────────────────────────
   The deck card is a poster; this is the whole thing. A clone, so the deck
   keeps its geometry and there is nothing to restore on close. These rules sit
   after the deck rules and match at the same specificity, so they win. */
.sheet[hidden]{display:none}    /* author display: wins over the UA's [hidden] */
.sheet{
  position:fixed;inset:0;z-index:60;
  display:flex;flex-direction:column;align-items:center;
  padding:24px 16px 0;
  overflow-y:auto;overscroll-behavior:contain;
  background:color-mix(in srgb,var(--void) 82%, transparent);
  backdrop-filter:blur(10px);
  opacity:0;transition:opacity .2s;
}
.sheet.on{opacity:1}
.sheet-inner{width:100%;max-width:min(560px,100%);margin:auto 0}
.sheet-hint{
  position:sticky;bottom:0;flex:none;
  padding:14px 0 18px;color:var(--faint);font-size:.8rem;text-align:center;
}

/* Undo every deck constraint on the cloned card. */
.sheet .card{
  position:static;inset:auto;height:auto;max-width:none;
  display:block;overflow:visible;
  padding:22px 24px 24px;cursor:default;transform:none;opacity:1;
  background:linear-gradient(180deg,var(--panel-2),var(--panel));
  transition:none;
}
.sheet .card::after,
.sheet .card::before{display:none}
.sheet .card > *{order:0}
.sheet .shot{
  order:0;height:auto;min-height:0;margin:15px 0 0;
  border:1px solid var(--line);border-radius:var(--radius-sm);box-shadow:none;
}
.sheet .shot img{height:auto;max-height:none}
.sheet .shot::after{display:none}
.sheet .shot-none{display:none}   /* the modal is the full record, not a poster */
.sheet .kicker{margin:0 0 9px}
.sheet .idea{-webkit-line-clamp:none;display:block;overflow:visible}
.sheet .note{overflow:visible;margin-top:17px}
.sheet .note .next{display:block}     /* the opportunity comes back here */
.sheet .quote{display:block}
.sheet .card h3{font-size:1.42rem}

@media (prefers-reduced-motion:reduce){.sheet{transition:none}}
