:root {
  color-scheme: dark;
  --bg: #100f0f;
  --surface: #1c1b1a;
  --raised: #282726;
  --border: #343331;
  --border-hi: #403e3c;
  --text: #cecdc3;
  --muted: #878580;
  --paper: #fffcf0;
  --accent: #3aa99f;
  --accent-strong: #48b8ae;
  --warm: #d0a215;
  --orange: #da702c;
  --purple: #8b7ec8;
  --magenta: #ce5d97;
  --blue: #4385be;
  --green: #879a39;
  --red: #d14d41;
  --cyan: #3aa99f;
  --serif: Iowan Old Style, Palatino Nova, Palatino, Book Antiqua, Georgia, serif;
  --sans: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica Neue, sans-serif;
  --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

* { box-sizing: border-box; }
html { min-height: 100%; background: var(--bg); scroll-behavior: smooth; }
body {
  min-height: 100%;
  margin: 0;
  color: var(--text);
  background: var(--bg);
  font: 16px/1.65 var(--sans);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
#sky { position: fixed; inset: 0; z-index: 0; pointer-events: none; overflow: hidden; }
.stars { position: absolute; top: 0; left: 0; border-radius: 50%; will-change: transform; }
@keyframes twinkle { 0%, 100% { opacity: 1; } 50% { opacity: .55; } }
.l2 { animation: twinkle 5.5s ease-in-out infinite; }
.l3 { animation: twinkle 8s ease-in-out infinite 2s; }
#page { position: relative; z-index: 1; }
a { color: var(--accent); }
a:hover { color: var(--accent-strong); }
a:focus-visible { outline: 2px solid var(--warm); outline-offset: 3px; }
.site-header { border-bottom: 1px solid var(--border); background: rgb(16 15 15 / .76); }
.site-header > div, main, footer { width: min(100% - 2.5rem, 68rem); margin: 0 auto; }
.site-header > div { display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: 1.1rem 0; }
.brand { display: inline-flex; align-items: center; gap: .5rem; color: var(--paper); font: 500 1.3rem/1 var(--serif); text-decoration: none; letter-spacing: .01em; }
.brand:hover { color: var(--paper); }
.brand-mark { height: 1.5rem; width: auto; }
.site-header nav { display: flex; align-items: center; gap: 1rem; flex-wrap: wrap; font: .75rem/1 var(--mono); letter-spacing: .08em; text-transform: uppercase; }
main { padding: 4rem 0 5rem; }
h1, h2, h3 { color: var(--paper); font-family: var(--serif); font-weight: 500; line-height: 1.2; text-wrap: balance; }
h1 { margin: 0; font-size: clamp(2.5rem, 6vw, 4.3rem); }
h2 { margin-top: 3.5rem; font-size: clamp(1.5rem, 3vw, 2.25rem); }
h3 { margin: 0; font-size: 1.25rem; }
p { max-width: 68ch; }
.eyebrow { margin: 0 0 .7rem; color: var(--warm); font: 600 .72rem/1 var(--mono); letter-spacing: .18em; text-transform: uppercase; }
.hero { padding: 2rem 0 3.25rem; border-bottom: 1px solid var(--border); }
/* A project page's hero: eyebrow + copy on the left, its card art (emoji/image)
   large on the right, art centred over the full left-column height. Laid out with
   named areas (eyebrow and copy are separate grid items) so the mobile stack can
   slot the art between the eyebrow and the title. */
.project-hero { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 340px); grid-template-areas: "eyebrow art" "copy art"; column-gap: 40px; row-gap: 0; align-items: center; }
.project-hero > .eyebrow { grid-area: eyebrow; }
.project-hero > .copy { grid-area: copy; min-width: 0; }
.project-hero > .art { grid-area: art; align-self: center; display: flex; align-items: center; justify-content: center; }
.project-hero .art .hero-emoji { font-size: clamp(88px, 20vw, 190px); line-height: 1; }
.project-hero .art img.mascot { width: min(240px, 55vw); height: auto; }
@media (max-width: 760px) {
  /* Single column, art between the eyebrow and the title (grid areas reorder to
     eyebrow → art → copy) so the emoji/image reads as a title-adjacent icon
     instead of dropping below the tagline, buttons, and note. Scaled down here. */
  .project-hero { grid-template-columns: 1fr; grid-template-areas: "eyebrow" "art" "copy"; }
  .project-hero > .art { justify-content: flex-start; margin: .5rem 0 .9rem; }
  .project-hero .art .hero-emoji { font-size: clamp(64px, 18vw, 118px); }
  .project-hero .art img.mascot { width: min(150px, 40vw); }
}
.tagline { max-width: 45rem; margin: 1rem 0; color: var(--paper); font: 1.25rem/1.45 var(--serif); }
.purpose { color: var(--muted); }
.deck { display: grid; grid-template-columns: repeat(auto-fill, minmax(178px, 200px)); justify-content: start; gap: 20px; margin-top: 1.5rem; }
.flip { position: relative; aspect-ratio: 5 / 7; perspective: 1100px; cursor: pointer; }
.flip:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; border-radius: 18px; }
.flip-inner { position: absolute; inset: 0; transform-style: preserve-3d; transition: transform .65s cubic-bezier(.2, .7, .25, 1); }
.flip.on .flip-inner { transform: rotateY(180deg); }
.face {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 20px 18px;
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: 18px;
  background: linear-gradient(165deg, var(--raised), var(--surface) 58%);
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}
.face::after { content: ""; position: absolute; inset: 7px; border: 1px solid rgb(255 252 240 / .055); border-radius: 12px; pointer-events: none; }
.face::before { content: ""; position: absolute; top: 0; left: 18px; right: 18px; height: 1px; background: linear-gradient(90deg, transparent, var(--hue, var(--border-hi)), transparent); }
.face.back { justify-content: space-between; transform: rotateY(180deg); }
/* Plated cards (fronts carrying full-plate artwork): the plate's own drawn
   frame is the border, so the front loses the card chrome; text shrinks so
   the art can breathe. Backs keep the standard card look. */
.flip.plated .face.front { padding: 13px 13px 12px; border: 0; }
.flip.plated .face.front::after { content: none; }
.flip.plated .face.front::before { left: 13px; right: 13px; }
.flip.plated .face.front h3 { font-size: 1.02rem; }
.flip.plated .face.front .tagline { color: var(--muted); font: .8rem/1.2 var(--serif); }
/* Benefit/beat gallery cards color their tagline with the card's hue — the same
   accent treatment the live/pilot/draft status labels get. Project cards (in
   .deck) keep the grey above. */
.benefits .flip.plated .face.front .tagline { color: var(--hue, var(--muted)); }
.flip.plated .face.front .art { margin: 0 0 6px; }
.glyph { color: var(--hue, var(--muted)); font-size: 1rem; }
.face h3 { margin: 4px 0 0; font: 500 1.28rem/1.25 var(--serif); }
.face .tagline { margin: 0; color: var(--muted); font-size: .88rem; }
.face .foot { display: flex; align-items: center; justify-content: space-between; margin-top: auto; color: var(--muted); font: .78rem/1 var(--mono); }
.face .status { color: var(--hue, var(--text)); text-transform: uppercase; letter-spacing: .08em; font-size: .68rem; }
.face.back p { margin: 0; color: var(--text); font-size: .9rem; }
/* Backs that carry a button clamp their body so the button is never pushed out
   of the card; overflow past the clamp ends in an ellipsis. */
.face.back.linked { justify-content: flex-start; gap: 12px; }
.face.back.linked p { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 7; line-clamp: 7; overflow: hidden; }
.face.back.linked .pill { margin-top: auto; flex-shrink: 0; }
.pill { align-self: flex-start; padding: 8px 16px; border: 1px solid var(--hue, var(--border-hi)); border-radius: 999px; color: var(--hue, var(--text)); background: none; font: 600 .8rem/1 var(--sans); text-decoration: none; }
.pill:hover { background: rgb(255 252 240 / .05); color: var(--paper); }
.hint { color: var(--muted); font: .68rem/1 var(--mono); letter-spacing: .06em; }
.doc-list { padding-left: 1.2rem; }
.doc-list li { margin: .4rem 0; }
/* Play gallery: distinct cards so each build reads as its own thing (the plain
   guide-list card style is scoped to showcase pages; this works in reading too). */
.embed-list { display: grid; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); gap: 16px; margin: 1.4rem 0 0; padding: 0; list-style: none; }
.embed-list a { display: flex; height: 100%; flex-direction: column; gap: 10px; padding: 20px; border: 1px solid var(--border); border-radius: 14px; background: linear-gradient(165deg, var(--raised), var(--surface) 58%); color: var(--text); text-decoration: none; transition: transform .18s ease, border-color .18s ease; }
.embed-list a:hover { border-color: var(--accent); transform: translateY(-2px); }
.embed-list h3 { margin: 0; color: var(--paper); }
.embed-list p { margin: 0; color: var(--muted); font-size: .92rem; line-height: 1.5; }
.embed-list span { margin-top: auto; align-self: flex-start; padding-top: 4px; color: var(--accent); font: .78rem/1 var(--mono); }
/* The transparency note between a project's public card data (the hero) and its
   published pages: what follows is only the owners' chosen public slice, not the
   real project files. Themed via variables so it reads in light and dark alike. */
.public-note { max-width: 42rem; margin: 1.75rem 0 2.75rem; padding: .9rem 1.15rem; border: 1px solid var(--border); border-left: 3px solid var(--warm); border-radius: .5rem; background: var(--surface); }
/* In the showcase layout the note rides in the same flex child as the hero, so
   its top margin is the only gap to the hero and its bottom margin drops out —
   the section-level flex gap already spaces it from the content below. */
.showcase-head .public-note { margin-bottom: 0; }
.public-note p { margin: 0; color: var(--muted); font: .9rem/1.6 var(--sans); }
.public-note strong { color: var(--text); font-weight: 600; }

article { max-width: 42rem; font-family: var(--serif); font-size: 1.15rem; line-height: 1.72; }
/* Give the title room to breathe above the first paragraph (~one blank line). */
article h1 { margin-bottom: 1.6rem; }
article p { margin: 0 0 1.35em; max-width: none; }
/* Scene break: a `---` between prose blocks becomes a centred ornament, not a rule. */
article hr { border: 0; margin: 2.4em 0; color: var(--warm); text-align: center; }
article hr::before { content: "✦"; font-size: .9rem; letter-spacing: .4em; opacity: .7; }
article img { max-width: 100%; height: auto; border-radius: .6rem; }
article pre { overflow: auto; padding: 1rem; border: 1px solid var(--border); border-radius: .6rem; background: var(--surface); }
article code { font-family: var(--mono); }
article :not(pre) > code { padding: .1em .3em; border-radius: .25em; background: var(--surface); }
article blockquote { margin-left: 0; padding-left: 1rem; border-left: 3px solid var(--border-hi); color: var(--muted); }
article table { display: block; max-width: 100%; overflow: auto; border-collapse: collapse; }
article th, article td { padding: .4rem .65rem; border: 1px solid var(--border); text-align: left; }
article th { color: var(--paper); background: var(--surface); }
/* On the legal index, the single "public set" table becomes a grid of document
   cards (title = link, second column = what it governs). Other prose is untouched. */
.page-legal article table { display: block; overflow: visible; border: 0; margin: 1.8em 0; }
.page-legal article thead { display: none; }
.page-legal article tbody { display: grid; grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr)); gap: 16px; }
.page-legal article tr { position: relative; display: flex; flex-direction: column; gap: 8px; padding: 18px 20px; border: 1px solid var(--border); border-radius: 14px; background: linear-gradient(165deg, var(--raised), var(--surface) 58%); transition: border-color .18s ease, transform .18s ease; }
.page-legal article tr:hover { border-color: var(--accent); transform: translateY(-2px); }
.page-legal article td { display: block; padding: 0; border: 0; }
.page-legal article td:first-child { font: 500 1.14rem/1.3 var(--serif); }
.page-legal article td:first-child a { color: var(--paper); text-decoration: none; }
/* Stretch the title link across the whole card so the entire card is clickable. */
.page-legal article td:first-child a::after { content: ""; position: absolute; inset: 0; border-radius: 14px; }
.page-legal article tr:hover td:first-child a { color: var(--accent); }
.page-legal article td:last-child { color: var(--muted); font-size: .9rem; line-height: 1.5; }
a.back { display: inline-block; margin-bottom: 2rem; }
footer { padding: 1.5rem 0 3rem; border-top: 1px solid var(--border); color: var(--muted); font: .78rem/1.6 var(--mono); letter-spacing: .04em; }
footer .social { display: flex; flex-wrap: wrap; gap: 1.25rem; margin-bottom: .6rem; }
footer .social a { color: var(--muted); text-decoration: none; }
footer .social a:hover { color: var(--paper); }
footer .social-note { margin: 0 0 .6rem; max-width: 46rem; font-style: italic; opacity: .82; }
.layout-showcase footer .social { justify-content: center; }
.layout-showcase footer .social-note { margin-inline: auto; }
/* Request-access header button — the invite-only stand-in for "Sign in". */
.site-header nav a.request { color: #08211e; background: var(--accent); border: 1px solid var(--accent); border-radius: 999px; padding: .4em .95em; text-decoration: none; text-transform: none; letter-spacing: 0; font-weight: 600; white-space: nowrap; }
.site-header nav a.request:hover { background: var(--accent-strong); border-color: var(--accent-strong); }
:root[data-theme="light"] .site-header nav a.request { color: #f7f0dd; }
/* Mobile header: keep the brand and the request/toggle controls on one aligned
   row — the request pill compacts so nothing wraps to its own misaligned line. */
@media (max-width: 640px) {
  .site-header > div { gap: .6rem; }
  .site-header nav, .layout-showcase .site-header nav { flex-wrap: nowrap; gap: .5rem; }
  .site-header nav a.request { padding: .38em .72em; font-size: .8rem; }
}
.layout-showcase .site-header { border: 0; background: transparent; }
.layout-showcase .site-header > div { width: min(100% - 3rem, 1140px); gap: 1rem; padding: 22px 0; }
.layout-showcase .site-header nav { gap: 22px; color: var(--muted); font: .85rem/1 var(--sans); letter-spacing: 0; text-transform: none; }
.layout-showcase main { width: min(100% - 3rem, 1140px); padding: 0; display: flex; flex-direction: column; gap: 120px; }
.layout-showcase h1, .layout-showcase h2 { line-height: 1.15; }
.layout-showcase h1 { font-size: clamp(2.4rem, 5.2vw, 3.6rem); letter-spacing: -.01em; }
.layout-showcase h2 { margin: 0; font-size: clamp(1.5rem, 3vw, 2.1rem); }
.layout-showcase section > header { display: flex; flex-direction: column; gap: 14px; max-width: 46rem; margin-bottom: 34px; }
.layout-showcase section > header p { margin: 0; color: var(--muted); }
/* Height follows the content (the card art / mascot); forcing a tall viewport
   height just opened an empty gap under the hero on larger screens. */
.layout-showcase #hero { display: grid; grid-template-columns: minmax(0, 1fr) 440px; gap: 40px; align-items: center; padding: 30px 0 0; border: 0; }
.layout-showcase #hero .copy { display: flex; flex-direction: column; gap: 22px; }
.layout-showcase #hero .sub { max-width: 34rem; margin: 0; color: var(--text); font-size: 1.13rem; }
.layout-showcase .cta-row { display: flex; flex-wrap: wrap; align-items: center; gap: 14px; }
.layout-showcase .btn { display: inline-flex; align-items: center; padding: 13px 26px; border: 1px solid transparent; border-radius: 999px; background: none; font: 600 .95rem/1 var(--sans); text-decoration: none; transition: transform .18s ease, background .18s ease, border-color .18s ease; }
.layout-showcase .btn:hover { transform: translateY(-1px); }
.layout-showcase .btn.primary { background: var(--accent); color: #08211e; }
.layout-showcase .btn.primary:hover { background: var(--accent-strong); color: #08211e; }
.layout-showcase .btn.ghost { border-color: var(--border-hi); color: var(--text); }
.layout-showcase .btn.ghost:hover { border-color: var(--accent); color: var(--accent); }
/* Request-access actions on project pages (reading layout, so self-contained —
   the showcase .btn rules above don't reach here). Clone / ask-to-join both link
   to the access form while onboarding is invite-only. */
.access-actions { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 6px; }
.access-actions .btn { display: inline-flex; align-items: center; padding: 12px 24px; border: 1px solid transparent; border-radius: 999px; font: 600 .95rem/1 var(--sans); text-decoration: none; transition: transform .18s ease, background .18s ease, border-color .18s ease; }
.access-actions .btn:hover { transform: translateY(-1px); }
/* One-line reassurance under the copy/join buttons: a copy takes only the public
   parts, private files stay put — reads to both the person copying and the owner. */
.access-note { max-width: 42rem; margin: .85rem 0 0; color: var(--muted); font: .82rem/1.5 var(--sans); }
.access-actions .btn.primary { background: var(--accent); color: #08211e; }
.access-actions .btn.primary:hover { background: var(--accent-strong); }
.access-actions .btn.ghost { border-color: var(--border-hi); color: var(--text); }
.access-actions .btn.ghost:hover { border-color: var(--accent); color: var(--accent); }
:root[data-theme="light"] .access-actions .btn.primary { color: #f7f0dd; }
.layout-showcase .fine { color: var(--muted); font: .72rem/1.8 var(--mono); letter-spacing: .04em; }
/* Solo hero art: a single artwork centred in the right column. */
.layout-showcase #hero .art.bare { height: auto; min-height: 0; display: flex; align-items: center; justify-content: center; }
.layout-showcase #hero .art.bare .mascot { width: min(420px, 44vw); height: auto; }
/* Solo showcase hero (the comic): eyebrow lifted out as a grid sibling, art
   centred over the full left-column height. Mirrors the reading-layout project
   hero so the mobile stack (below) can put the art between eyebrow and title. */
.layout-showcase #hero.hero-solo { grid-template-areas: "eyebrow art" "copy art"; row-gap: 22px; }
.layout-showcase #hero.hero-solo > .eyebrow { grid-area: eyebrow; }
.layout-showcase #hero.hero-solo > .copy { grid-area: copy; }
.layout-showcase #hero.hero-solo > .art { grid-area: art; align-self: center; }
/* Fallback hero art when a project pictures itself with just its card emoji. */
.layout-showcase #hero .art .hero-emoji { font-size: clamp(96px, 28vw, 220px); line-height: 1; }
@keyframes bob { from { translate: 0 -7px; } to { translate: 0 7px; } }
.bob { animation: bob 6s ease-in-out infinite alternate; }
.layout-showcase .deck { margin-top: 0; }
.layout-showcase .benefits { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 20px; }
.layout-showcase .benefits .flip { height: 212px; aspect-ratio: auto; }
.layout-showcase .benefits.gallery { grid-template-columns: repeat(auto-fill, minmax(178px, 200px)); justify-content: start; }
.layout-showcase .benefits.gallery .flip { height: auto; aspect-ratio: 5 / 7; }
.face .art { flex: 1; min-height: 0; margin: 2px 0 8px; display: flex; align-items: center; justify-content: center; overflow: hidden; }
/* One rule for every emoji card: the glyph sizes to its box (a size container),
   capped at 3.6rem. Cards with room show it full; a card squeezed by a long title
   shrinks the glyph to fit rather than clipping it. Same treatment everywhere —
   deck cards and the hero's floating minis alike. */
.face .art.solo { font-size: 3.6rem; line-height: 1; container-type: size; }
.face .art.solo > span { font-size: min(3.6rem, 86cqh, 86cqw); }
.face .art.grid { display: grid; grid-template-columns: 1fr 1fr; gap: 6px 16px; place-items: center; font-size: 2rem; }
.face .art img { max-width: 100%; max-height: 100%; object-fit: contain; border-radius: 10px; }
.layout-showcase .guide-list { display: grid; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); gap: 16px; margin: 0; padding: 0; list-style: none; }
.layout-showcase .guide-list a { display: flex; min-height: 9rem; flex-direction: column; justify-content: space-between; padding: 20px; border: 1px solid var(--border); border-radius: 14px; background: linear-gradient(165deg, var(--raised), var(--surface) 58%); color: var(--text); text-decoration: none; transition: transform .18s ease, border-color .18s ease; }
.layout-showcase .guide-list a:hover { border-color: var(--accent); color: var(--paper); transform: translateY(-2px); }
.layout-showcase .guide-list h3 { margin: 0; }
.layout-showcase .guide-list span { color: var(--accent); font: .78rem/1 var(--mono); }
/* Closing call-to-action panel (the `cta` section): a quiet framed invitation,
   left-aligned to sit flush with the section headers above it. */
.layout-showcase .cta-panel { display: flex; justify-content: flex-start; text-align: left; }
.layout-showcase .cta-panel > div { display: flex; flex-direction: column; align-items: flex-start; gap: 18px; max-width: 46rem; padding: 40px 40px; border: 1px solid var(--border-hi); border-radius: 20px; background: linear-gradient(165deg, var(--raised), var(--surface) 60%); }
.layout-showcase .cta-panel h2 { margin: 0; }
.layout-showcase .cta-panel p { margin: 0; color: var(--text); font-size: 1.08rem; }
.layout-showcase .cta-panel .btn { margin-top: 8px; }
.layout-showcase footer { width: 100%; border: 0; padding: 70px 20px 46px; text-align: center; }
.layout-showcase footer p { margin-inline: auto; }

/* ── Theme toggle ─────────────────────────────────────────────────────────── */
.theme-toggle {
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; padding: 0;
  border: 1px solid var(--border-hi); border-radius: 999px;
  background: transparent; color: var(--text);
  font-size: 1rem; line-height: 1; cursor: pointer;
  transition: color .18s ease, border-color .18s ease, background .18s ease;
}
.theme-toggle:hover { color: var(--paper); border-color: var(--accent); }
.theme-toggle:focus-visible { outline: 2px solid var(--warm); outline-offset: 3px; }

/* ── Promoted pair + the "too many cards" table scatter ───────────────────── */
/* Two heading levels here. GROUP headers ("Our projects", "Community Projects")
   are the top level: bright serif, each opening a boundary rule so you can see
   where one group ends and the next begins. TIER headers (live/pilot/draft) sit
   a level down: small mono caps with a status-colored dot. */
.deck-label { margin: 0 0 18px; color: var(--paper); font: 600 1.15rem/1.2 var(--serif); letter-spacing: 0; text-transform: none; }
.promoted { margin-bottom: 8px; }
/* Mahanu + the comic: two real-proportioned cards, thinner, left-aligned. */
.promoted .deck { display: flex; flex-wrap: wrap; justify-content: flex-start; gap: 22px; grid-template-columns: none; margin-top: 0; }
.promoted .deck > .flip { flex: 0 0 auto; width: 196px; }
/* Boundary rule between the promoted group and the community group. */
.rest { margin-top: 48px; padding-top: 44px; border-top: 1px solid var(--border); }
/* Community projects split into live / pilot / draft piles, stacked vertically. */
.tier { margin-top: 34px; }
.tier:first-of-type { margin-top: 24px; }
.tier-label { display: flex; align-items: center; gap: 9px; margin: 0 0 14px; color: var(--muted); font: 600 .7rem/1 var(--mono); letter-spacing: .16em; text-transform: uppercase; }
.tier-label::before { content: ""; width: 8px; height: 8px; border-radius: 999px; background: var(--tier-hue, var(--muted)); box-shadow: 0 0 0 3px color-mix(in srgb, var(--tier-hue, var(--muted)) 22%, transparent); }
.tier-live { --tier-hue: var(--green); }
.tier-pilot { --tier-hue: var(--accent); }
.tier-draft { --tier-hue: var(--warm); }

/* Left-aligned so the label and the cards below it line up on the same edge. */
.card-group { position: relative; }
.card-group.stacked { display: flex; flex-direction: column; align-items: flex-start; gap: 18px; cursor: pointer; border-radius: 16px; }
.card-group.stacked:focus-visible { outline: 2px solid var(--accent); outline-offset: 8px; }
/* Cards laid out on a table, each overlapping the one before — not a tight deck.
   Overlap is a negative margin cancelled by the pile's left padding, so the
   left-most card lands flush with the label's edge whatever the card count. */
/* The cards fan out to the right and comfortably fit the column on any normal
   screen, so no clipping is needed here — the shadows fade into the page. Only
   narrow viewports (below) clip the horizontal overflow to keep the page from
   growing wider than the phone. */
.card-group.stacked .pile { display: flex; flex-wrap: nowrap; justify-content: flex-start; align-items: flex-start; gap: 0; grid-template-columns: none; width: 100%; padding: 32px 0 20px 74px; }
.card-group.stacked .pile > .flip {
  position: static; flex: 0 0 auto; width: 196px; height: 274px; margin-left: -74px;
  aspect-ratio: auto; transform-origin: 50% 60%;
  /* Round the flip itself so its drop shadow follows the card's rounded corners
     rather than casting a square one behind the rounded face. */
  border-radius: 18px;
  box-shadow: 0 10px 24px rgb(0 0 0 / .42);
  transition: transform .35s cubic-bezier(.2, .7, .25, 1);
}
/* Only a handful rest on the table; the remainder fan out on tap. */
.card-group.stacked .pile > .flip:nth-last-child(n+7) { display: none; }
/* Tilts + vertical jitter so they read as dropped by hand, not machine-set. */
.card-group.stacked .pile > .flip:nth-child(6n+1) { transform: rotate(-6deg) translateY(14px); }
.card-group.stacked .pile > .flip:nth-child(6n+2) { transform: rotate(4deg) translateY(-8px); }
.card-group.stacked .pile > .flip:nth-child(6n+3) { transform: rotate(-2.5deg) translateY(6px); }
.card-group.stacked .pile > .flip:nth-child(6n+4) { transform: rotate(6deg) translateY(-4px); }
.card-group.stacked .pile > .flip:nth-child(6n+5) { transform: rotate(-4.5deg) translateY(11px); }
.card-group.stacked .pile > .flip:nth-child(6n) { transform: rotate(2.5deg) translateY(-10px); }
/* Lift the top card on hover/focus so the group invites a tap. */
.card-group.stacked:hover .pile > .flip:nth-last-child(1),
.card-group.stacked:focus-visible .pile > .flip:nth-last-child(1) { transform: rotate(4deg) translateY(-12px); }
.card-group.stacked .flip-inner { transition: none; }
.deck-spread { display: inline-flex; align-items: center; gap: .45em; color: var(--muted); font: .78rem/1 var(--mono); letter-spacing: .06em; }
.deck-spread b { color: var(--accent); font-weight: 600; }
.card-group:not(.stacked) .deck-spread { display: none; }
/* Opened: deal each card into the normal grid with a small stagger. */
@keyframes dealIn { from { opacity: 0; transform: translateY(12px) scale(.97); } to { opacity: 1; transform: none; } }
.card-group.spread .flip { animation: dealIn .5s cubic-bezier(.2, .7, .25, 1) both; animation-delay: calc(min(var(--i, 0), 24) * 20ms); }

/* ── Light theme: hand-made paper, coffee, and pastel water-colour ────────── */
:root[data-theme="light"] {
  color-scheme: light;
  --bg: #ece3cf;
  --surface: #f7f0dd;
  --raised: #fffdf4;
  --border: #ddd2ba;
  --border-hi: #c9bb9c;
  --text: #4a4234;
  --muted: #8c8168;
  --paper: #362f21;
  --accent: #1c7d74;
  --accent-strong: #14655d;
  --warm: #ad8301;
  --orange: #bc5215;
  --purple: #5e409d;
  --magenta: #a02f6f;
  --blue: #205ea6;
  --green: #66800b;
  --red: #af3029;
  --cyan: #24837b;
}
:root[data-theme="light"] .stars { display: none; }
/* The paper wash: soft, irregular pastel blooms and warm light-coffee tones over
   a cream ground. All elliptical and feathered — no hard rings. Painted on the
   fixed #sky so it sits behind everything. */
:root[data-theme="light"] #sky {
  background-color: var(--bg);
  background-repeat: no-repeat;
  background-image:
    radial-gradient(38% 40% at 14% 16%, rgb(120 190 175 / .22), transparent 70%),
    radial-gradient(34% 30% at 86% 22%, rgb(224 150 168 / .18), transparent 72%),
    radial-gradient(42% 42% at 80% 82%, rgb(196 158 110 / .22), transparent 72%),
    radial-gradient(44% 40% at 6% 86%, rgb(160 150 214 / .18), transparent 72%),
    radial-gradient(30% 26% at 58% 54%, rgb(198 160 108 / .18), transparent 74%),
    radial-gradient(28% 22% at 24% 46%, rgb(176 138 90 / .14), transparent 76%);
}
/* Fine paper grain, tiled, on top of the wash. */
:root[data-theme="light"] #sky::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.05'/%3E%3C/svg%3E");
}
:root[data-theme="light"] .site-header { background: rgb(240 233 214 / .82); }
:root[data-theme="light"] .face { box-shadow: 0 1px 2px rgb(70 54 28 / .10), 0 10px 24px rgb(70 54 28 / .09); }
:root[data-theme="light"] .card-group.stacked .pile > .flip { box-shadow: 0 12px 26px rgb(70 54 28 / .24); }
:root[data-theme="light"] .layout-showcase .guide-list a,
:root[data-theme="light"] .layout-showcase .cta-panel > div { box-shadow: 0 1px 2px rgb(70 54 28 / .08), 0 12px 26px rgb(70 54 28 / .07); }
:root[data-theme="light"] .pill:hover { background: rgb(54 47 33 / .06); }
:root[data-theme="light"] .btn.primary { color: #f7f0dd; }
:root[data-theme="light"] .btn.primary:hover { color: #fffdf4; }

/* On narrow screens the fanned cards would run past the column and widen the
   page; clip only the horizontal overflow (overflow-y stays visible, so the
   drop shadows are never cut into a rectangle). */
@media (max-width: 820px) { .card-group.stacked .pile { overflow-x: clip; } }
@media (prefers-reduced-motion: reduce) { .l2, .l3 { animation: none; } .flip-inner { transition: none; } }
@media (prefers-reduced-motion: reduce) { .bob { animation: none; } .card-group.stacked .pile > .flip { transition: none; } .card-group.spread .flip { animation: none; } }
/* Mobile: single column, art stacked between the eyebrow and the title. */
@media (max-width: 960px) {
  .layout-showcase #hero { grid-template-columns: 1fr; min-height: auto; }
  /* Stack eyebrow → art → copy so the artwork sits by the title, left-aligned,
     like the reading-layout project heroes. */
  .layout-showcase #hero.hero-solo { grid-template-areas: "eyebrow" "art" "copy"; row-gap: 16px; }
  .layout-showcase #hero.hero-solo > .art { width: auto; height: auto; margin: .25rem 0 .5rem; justify-content: flex-start; }
  .layout-showcase #hero.hero-solo > .art .mascot { width: min(300px, 68vw); }
}
@media (max-width: 38rem) { main { padding-top: 2.5rem; } .layout-showcase main { gap: 72px; } }
