/* ============================================================
   SHARED STYLES — tokens, base, nav, buttons, cards, footer.
   Mirrors DESIGN.md. Page-specific rules stay in their page.
   ============================================================ */
:root{
  --accent:#00fc19;
  --accent-ink:#00fc19;
  --accent-soft:rgba(0,252,25,.12);
  --accent-line:rgba(0,252,25,.20);
  --accent-glow:rgba(0,252,25,.38);

  --bg:#060807;
  --bg-2:#0b0e0c;
  --surface:#0d100e;
  --surface-2:#141814;
  --hairline:rgba(232,237,233,.10);
  --hairline-2:rgba(232,237,233,.06);

  --ink:#e9ede9;
  --ink-2:#b6bdb8;
  --muted:#8a938c;

  --display:"Inter Tight","Inter",system-ui,-apple-system,sans-serif;
  --body:"Inter",system-ui,-apple-system,sans-serif;
  --mono:"JetBrains Mono",ui-monospace,SFMono-Regular,Menlo,monospace;

  --step--1:clamp(.78rem,.76rem + .1vw,.84rem);
  --step-0:clamp(.95rem,.92rem + .16vw,1.05rem);
  --step-1:clamp(1.1rem,1.02rem + .38vw,1.35rem);
  --step-2:clamp(1.45rem,1.25rem + .95vw,2.1rem);
  --step-3:clamp(2rem,1.5rem + 2.3vw,3.4rem);
  --step-4:clamp(2.4rem,1.5rem + 4.2vw,5rem);

  --s1:.5rem; --s2:.875rem; --s3:1.25rem; --s4:2rem;
  --s5:3rem; --s6:4.5rem; --s7:7rem; --s8:10rem;

  --radius:14px;
  --radius-lg:20px;
  --maxw:1240px;
  --gutter:clamp(1.25rem,4vw,3.5rem);

  --ease:cubic-bezier(.22,.61,.36,1);
  --ease-out:cubic-bezier(.16,1,.3,1);
}

@media (prefers-color-scheme: light){
  :root{
    --bg:#f6f8f6; --bg-2:#eef1ee; --surface:#ffffff; --surface-2:#f2f5f2;
    --hairline:rgba(10,13,11,.12); --hairline-2:rgba(10,13,11,.07);
    --ink:#0a0d0b; --ink-2:#333b35; --muted:#5c655e;
    /* #00fc19 as text on white fails AA. Fills keep the neon. */
    --accent-ink:#067d13;
    --accent-soft:rgba(0,252,25,.16);
    --accent-line:rgba(6,125,19,.28);
    --accent-glow:rgba(6,125,19,.22);
  }
}

*,*::before,*::after{box-sizing:border-box}

/* The `hidden` attribute is only as strong as the weakest author rule that
   sets `display` on the same element. `.hero-meta span{display:inline-flex}`
   silently defeated it: the attribute was present, el.hidden was true, and the
   element rendered anyway — so JS that "hides" something can appear to do
   nothing at all, with no error and nothing wrong in the DOM inspector.
   This is the same shape as the `.stat span` trap in DESIGN.md: a descendant
   selector reaching further than intended. !important is right here, because
   `hidden` is a statement about whether the element exists for the user, not
   a style suggestion to be negotiated. */
[hidden]{display:none !important}

/* Stands in for the width tabs on screenshot galleries, where those tabs
   would only scale a fixed image. See the comment in template.html. */
.pv-tabs-note{
  font-family:var(--mono);font-size:var(--step--1);letter-spacing:.06em;
  text-transform:uppercase;color:var(--muted);
}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
@media (prefers-reduced-motion: reduce){html{scroll-behavior:auto}}

body{
  margin:0;background:var(--bg);color:var(--ink);
  font-family:var(--body);font-size:var(--step-0);line-height:1.6;
  -webkit-font-smoothing:antialiased;overflow-x:hidden;
}
h1,h2,h3{font-family:var(--display);font-weight:600;line-height:1.05;letter-spacing:-.03em;margin:0}
p{margin:0}
a{color:inherit;text-decoration:none}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
input{font:inherit;color:inherit}
svg{display:block}

:focus-visible{outline:2px solid var(--accent-ink);outline-offset:3px;border-radius:4px}
::selection{background:var(--accent);color:#050705}

.skip{position:absolute;left:-9999px;top:0;z-index:200;background:var(--accent);color:#050705;padding:.75rem 1.25rem;font-weight:600}
.skip:focus{left:0}

.wrap{width:100%;max-width:var(--maxw);margin-inline:auto;padding-inline:var(--gutter)}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.section{padding-block:clamp(3.5rem,8vw,var(--s7))}

/* ---------- shared bits ---------- */
.eyebrow{
  font-family:var(--mono);font-size:var(--step--1);letter-spacing:.16em;
  text-transform:uppercase;color:var(--muted);
  display:flex;align-items:center;gap:.6rem;   /* gap applies only when an eyebrow has inline children of its own */
}
.lede{color:var(--ink-2);font-size:var(--step-1);line-height:1.55;max-width:56ch}

.btn{
  --btn-bg:var(--accent); --btn-ink:#050705;
  display:inline-flex;align-items:center;justify-content:center;gap:.6rem;
  padding:.95rem 1.6rem;min-height:48px;
  background:var(--btn-bg);color:var(--btn-ink);
  border:1px solid transparent;border-radius:999px;
  font-weight:600;font-size:var(--step-0);letter-spacing:-.01em;
  transition:transform .3s var(--ease-out),box-shadow .3s var(--ease-out),opacity .3s;
}
.btn:hover{box-shadow:0 0 0 6px var(--accent-soft),0 14px 40px -14px var(--accent-glow)}
.btn:active{transform:scale(.98)}
.btn .arw{transition:transform .3s var(--ease-out)}
.btn:hover .arw{transform:translateX(4px)}
.btn--ghost{--btn-bg:transparent;--btn-ink:var(--ink);border-color:var(--hairline)}
.btn--ghost:hover{border-color:var(--accent-line);box-shadow:0 0 0 6px var(--accent-soft)}
.btn[disabled],.btn[aria-disabled="true"]{opacity:.45;cursor:not-allowed;box-shadow:none}
.btn[disabled]:hover,.btn[aria-disabled="true"]:hover{box-shadow:none;transform:none}

/* ---------- nav ---------- */
.progress{position:fixed;inset:0 auto auto 0;height:2px;width:0%;background:var(--accent);box-shadow:0 0 12px var(--accent-glow);z-index:120;transition:width .1s linear}
.nav{position:fixed;top:0;left:0;right:0;z-index:110;border-bottom:1px solid transparent;transition:background .4s var(--ease),border-color .4s var(--ease)}
.nav.scrolled{background:color-mix(in srgb,var(--bg) 82%,transparent);backdrop-filter:blur(14px) saturate(140%);border-bottom-color:var(--hairline-2)}
.nav-in{display:flex;align-items:center;justify-content:space-between;gap:var(--s3);height:72px;transition:height .4s var(--ease)}
.nav.scrolled .nav-in{height:62px}

.brand{display:inline-flex;align-items:center;gap:.6rem;font-family:var(--display);font-weight:600;letter-spacing:-.02em;font-size:1.05rem}
.brand .mark{width:54px;height:28px;flex:none;background:url(/assets/brand/mark.png?v=b838b8c9) center/contain no-repeat;filter:drop-shadow(0 0 10px var(--accent-glow));animation:brandPulse 3.2s var(--ease) infinite}
@keyframes brandPulse{0%,100%{opacity:1}50%{opacity:.74}}
.brand-text{display:none}
@media (min-width:600px){.brand-text{display:inline}}
/* The neon reads as washed-out mint on the light background, the same
   reason --accent-ink exists. Darken the mark and drop the glow, which
   only muddies things against white. */
@media (prefers-color-scheme:light){
  .brand .mark{filter:brightness(.62) saturate(1.25)}
}

.nav-links{display:none;align-items:center;gap:var(--s4)}
@media (min-width:860px){.nav-links{display:flex}}
.nav-links a{position:relative;font-family:var(--mono);font-size:var(--step--1);letter-spacing:.06em;text-transform:uppercase;color:var(--muted);padding-block:.5rem;transition:color .25s}
.nav-links a::after{content:"";position:absolute;left:0;bottom:0;height:1px;width:0;background:var(--accent);transition:width .35s var(--ease-out)}
.nav-links a:hover,.nav-links a[aria-current="true"]{color:var(--ink)}
.nav-links a:hover::after,.nav-links a[aria-current="true"]::after{width:100%}

.nav-actions{display:flex;align-items:center;gap:var(--s2)}
/* Phase 2 drops sign-in here. Hidden until auth exists so we never ship a
   control that does nothing when clicked. */
.nav-signin{display:none;align-items:center;min-height:44px;font-family:var(--mono);font-size:var(--step--1);letter-spacing:.06em;text-transform:uppercase;color:var(--muted);transition:color .25s}
.nav-signin:hover{color:var(--ink)}
/* Visible at every width. It used to appear only above 600px, which left
   a phone with no way into an account at all: the nav collapses to the
   logo and one CTA, and buying requires being signed in. Reaching your
   purchases should not depend on the width of the screen. */
.nav-signin[data-phase2="ready"]{display:inline-flex}
.nav-cta{padding:.6rem 1.1rem;min-height:44px;font-size:var(--step--1);white-space:nowrap}

/* Menu. Below 860px the header has room for the mark, Sign in and one more
   control, and the text links (Templates, Studio work, Guides) used to be
   hidden with no way to reach them on a phone. The Menu takes the place of
   the Browse templates button there, since Templates is its first item.
   Built on <details>, so it opens and closes without JavaScript; app.js only
   adds closing on a link tap, an outside tap or Escape. */
.nav-menu{position:relative;display:none}
.nav-menu>summary{list-style:none;display:inline-flex;align-items:center;gap:.55rem;min-height:44px;padding:.55rem 1rem;border:1px solid var(--hairline);border-radius:999px;font-family:var(--mono);font-size:var(--step--1);letter-spacing:.06em;text-transform:uppercase;color:var(--ink);cursor:pointer;transition:border-color .25s}
.nav-menu>summary::-webkit-details-marker{display:none}
.nav-menu>summary .bars{display:inline-grid;gap:3px}
.nav-menu>summary .bars i{display:block;width:14px;height:1.5px;background:currentColor;transition:transform .25s var(--ease-out),opacity .2s}
.nav-menu[open]>summary{border-color:var(--accent-line)}
.nav-menu[open]>summary .bars i:first-child{transform:translateY(2.25px) rotate(45deg)}
.nav-menu[open]>summary .bars i:last-child{transform:translateY(-2.25px) rotate(-45deg)}
.nav-menu-panel{position:absolute;right:0;top:calc(100% + 10px);min-width:min(240px,calc(100vw - 2 * var(--gutter)));display:grid;padding:.4rem;background:var(--surface);border:1px solid var(--hairline);border-radius:var(--radius);box-shadow:0 24px 60px -24px rgba(0,0,0,.7)}
.nav-menu-panel a{display:flex;align-items:center;min-height:48px;padding:0 1rem;border-radius:10px;font-size:1rem;color:var(--ink)}
.nav-menu-panel a:hover,.nav-menu-panel a:focus-visible{background:var(--accent-soft)}
@media (max-width:859.98px){
  .nav-menu{display:block}
  .nav .nav-actions .nav-cta{display:none}
}

/* ---------- tags ---------- */
.tag{
  font-family:var(--mono);font-size:.68rem;letter-spacing:.1em;text-transform:uppercase;
  padding:.32rem .65rem;border-radius:999px;white-space:nowrap;
  border:1px solid var(--hairline);color:var(--muted);
}
.tag--free{color:var(--accent-ink);border-color:var(--accent-line);background:var(--accent-soft)}
.tag--premium{color:var(--ink);border-color:var(--hairline)}
.tag--soon{color:var(--muted)}

/* ---------- template cards ---------- */
.grid{display:grid;grid-template-columns:1fr;gap:var(--s3);list-style:none;margin:0;padding:0}
@media (min-width:640px){.grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (min-width:1040px){.grid{grid-template-columns:repeat(3,minmax(0,1fr))}}

.card{
  position:relative;background:var(--surface);
  border:1px solid var(--hairline-2);border-radius:var(--radius-lg);
  overflow:hidden;display:flex;flex-direction:column;
  transition:transform .4s var(--ease-out),border-color .4s var(--ease),box-shadow .4s var(--ease-out);
}
.card:hover,.card:focus-within{transform:translateY(-4px);border-color:var(--accent-line);box-shadow:0 20px 50px -24px rgba(0,0,0,.55)}
@media (prefers-reduced-motion: reduce){.card:hover,.card:focus-within{transform:none}}

.thumb{
  position:relative;aspect-ratio:16/10;background:var(--bg-2);
  border-bottom:1px solid var(--hairline-2);
  padding:12%;display:grid;gap:6%;overflow:hidden;
}
.thumb::after{content:"";position:absolute;inset:0;background:radial-gradient(90% 70% at 50% 0%,var(--accent-soft),transparent 65%);opacity:0;transition:opacity .45s var(--ease)}
.card:hover .thumb::after{opacity:1}
/* Photo variant: the image fills the same 16/10 box the wireframe uses, so
   swapping one for the other never changes the card's height. */
.thumb--photo{padding:0;display:block}
.thumb--photo picture,.thumb--photo img{display:block;width:100%;height:100%}
.thumb--photo img{object-fit:cover;object-position:top center}

.thumb i{display:block;background:var(--hairline);border-radius:3px}
.thumb .bar{height:8px}
.thumb .bar.sm{width:38%}
.thumb .bar.md{width:64%}
.thumb .accent{background:var(--accent);opacity:.85;height:8px;width:26%}
.thumb .block{border-radius:6px}
.thumb-row{display:flex;gap:6%}
.thumb-row i{flex:1}
.t-landing{grid-template-rows:auto auto auto 1fr}
.t-landing .block{min-height:22px}
.t-portfolio{grid-template-rows:auto 1fr}
.t-portfolio .grid2{display:grid;grid-template-columns:1fr 1fr;gap:6%}
.t-portfolio .grid2 i{border-radius:6px;min-height:20px}
.t-dashboard{grid-template-columns:28% 1fr;grid-template-rows:1fr;gap:6%}
.t-dashboard .side{border-radius:6px}
.t-dashboard .main{display:grid;grid-template-rows:auto 1fr;gap:12%}
.t-dashboard .main .block{border-radius:6px;min-height:20px}
.t-store{grid-template-rows:auto 1fr}
.t-store .grid3{display:grid;grid-template-columns:repeat(3,1fr);gap:5%}
.t-store .grid3 i{border-radius:5px;min-height:20px}

.card-body{padding:var(--s3);display:flex;flex-direction:column;gap:.6rem;flex:1}
.card-top{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--s2)}
.card h3{font-size:var(--step-1);letter-spacing:-.025em}
.card h3 a::after{content:"";position:absolute;inset:0;z-index:2}
.card-cat{font-family:var(--mono);font-size:.7rem;letter-spacing:.12em;text-transform:uppercase;color:var(--muted)}
.card p{color:var(--muted);font-size:var(--step-0);line-height:1.55;flex:1}
.card-foot{display:flex;align-items:center;justify-content:space-between;gap:var(--s2);padding-top:.85rem;margin-top:.2rem;border-top:1px solid var(--hairline-2)}
.price{font-family:var(--mono);font-size:var(--step-0);color:var(--ink);font-variant-numeric:tabular-nums}
.price .free{color:var(--accent-ink)}
.card-act{font-family:var(--mono);font-size:var(--step--1);letter-spacing:.08em;text-transform:uppercase;color:var(--muted);display:inline-flex;align-items:center;gap:.45rem;min-height:44px;transition:color .25s}
.card:hover .card-act{color:var(--accent-ink)}

/* ---------- footer ---------- */
.foot{border-top:1px solid var(--hairline-2);padding-block:var(--s4)}
.foot-in{display:flex;flex-wrap:wrap;gap:var(--s3);align-items:center;justify-content:space-between;font-family:var(--mono);font-size:var(--step--1);color:var(--muted)}
.foot-links{display:flex;flex-wrap:wrap;gap:var(--s3)}
.foot-links a:hover{color:var(--accent-ink)}

/* ---------- reveal ---------- */
[data-reveal]{opacity:0;transform:translateY(20px);transition:opacity .7s var(--ease-out),transform .7s var(--ease-out);transition-delay:var(--d,0ms)}
[data-reveal].in{opacity:1;transform:none}

@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{animation-duration:.001ms !important;animation-iteration-count:1 !important;transition-duration:.001ms !important}
  [data-reveal]{opacity:1;transform:none}
}

/* Closing call to action on a guide. Set apart from the prose deliberately: it
   is the one part of the page selling something, and a reader should be able to
   tell that at a glance rather than discovering it mid-paragraph. */
.post-cta{margin-top:var(--s4);padding:var(--s3);border:1px solid var(--hairline-2);border-radius:var(--radius);background:var(--surface)}
.post-cta h2{margin-top:0}
.post-cta p{color:var(--muted)}
/* .doc a is 0-1-1 and .btn is 0-1-0, so inside prose the link colour won and
   painted the label var(--accent-ink) on a var(--accent) pill. The text was
   always there, just the same green as the background it sat on. */
.post-cta .btn{margin-top:.5rem;color:var(--btn-ink)}
/* Guide index. */
.post-list{list-style:none;padding:0;margin:0}
.post-list li{list-style:none;padding-block:var(--s3);border-top:1px solid var(--hairline-2)}
.post-list h2{margin:0 0 .25rem}
.post-list p{margin:.25rem 0 0}

/* The summary at the top of a guide. Set apart from the prose because it is
   doing a different job: a reader deciding whether to spend the next four
   minutes, and an AI system looking for one extractable paragraph that answers
   the question without needing the rest of the page. */
.tldr{margin:var(--s3) 0;padding:var(--s3);border-left:2px solid var(--accent);background:var(--surface);border-radius:0 var(--radius) var(--radius) 0}
.tldr p{margin:0}
.tldr-label{font-family:var(--mono);font-size:var(--step--1);letter-spacing:.06em;text-transform:uppercase;color:var(--muted);margin-bottom:.4rem !important}

/* ---------------------------------------------------------------- help centre
   The structure is a search box over a browsable list, which is the shape a
   help centre has because it serves two people: one who knows the words for
   their problem, and one who does not and needs to see the options.

   Categories stay open rather than collapsing into accordions. A collapsed
   section hides its contents from find-in-page, which is how a lot of people
   search a page when they have not spotted the search box, and it costs a
   click to reach an answer someone is already frustrated to be looking for. */
.help-search{margin:var(--s4) 0 var(--s5)}
.help-search label{display:block;font-family:var(--mono);font-size:var(--step--1);letter-spacing:.06em;text-transform:uppercase;color:var(--muted);margin-bottom:var(--s2)}
.help-search input{width:100%;font:inherit;font-size:var(--step-1);padding:.85rem 1rem;color:var(--ink);background:var(--surface);border:1px solid var(--hairline);border-radius:var(--radius)}
.help-search input:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-color:transparent}
.help-search input::placeholder{color:var(--muted)}
.help-count{font-family:var(--mono);font-size:var(--step--1);color:var(--muted);margin:var(--s2) 0 0}

.help-group{margin-bottom:var(--s5)}
.help-group h2{font-size:var(--step-1);margin:0 0 var(--s3);padding-bottom:var(--s2);border-bottom:1px solid var(--hairline-2)}
.help-group ul{list-style:none;margin:0;padding:0}
.help-group li{padding-block:var(--s3);border-bottom:1px solid var(--hairline-2)}
.help-group li a{font-size:var(--step-1);text-decoration:none;box-shadow:inset 0 -1px 0 var(--accent-line)}
.help-group li a:hover{box-shadow:inset 0 -1px 0 var(--accent)}
.help-group li p{margin:.4rem 0 0;color:var(--muted);font-size:var(--step-0)}
.help-none{color:var(--muted);padding:var(--s4) 0}

.help-crumb{font-family:var(--mono);font-size:var(--step--1);color:var(--muted);margin-bottom:var(--s3)}
.help-crumb a{color:var(--ink-2)}
.help-crumb span{margin-inline:.35rem}

/* The prose sits in .doc-in at 68ch, so the article needs no width of its own.
   Only the two things around it do. */
.help-foot{margin-top:var(--s5);padding-top:var(--s3);border-top:1px solid var(--hairline-2);color:var(--muted);font-size:var(--step-0)}
.help-related{margin-top:var(--s5);padding:var(--s3);border:1px solid var(--hairline-2);border-radius:var(--radius);background:var(--surface)}
.help-related h2{font-size:var(--step-0);font-family:var(--mono);letter-spacing:.06em;text-transform:uppercase;color:var(--muted);margin:0 0 var(--s2)}
.help-related ul{list-style:none;margin:0;padding:0;display:grid;gap:var(--s2)}
.help-related a{text-decoration:none;box-shadow:inset 0 -1px 0 var(--accent-line)}
.help-related a:hover{box-shadow:inset 0 -1px 0 var(--accent)}
/* The home page FAQ answers the pre-purchase questions only. This points at
   the rest rather than growing that list until nobody reads any of it. */
.faq-more{margin-top:var(--s4);padding-top:var(--s3);border-top:1px solid var(--hairline-2);color:var(--muted);font-size:var(--step-0)}

/* ---------------------------------------------------------
   WAITLIST FORM — one component on the store, every template
   page and every guide. app.js drives any form[data-waitlist].
   --------------------------------------------------------- */
.wl-form{display:flex;flex-wrap:wrap;gap:var(--s2);margin-top:var(--s4);max-width:520px}
.wl-form .fieldwrap{flex:1 1 240px;display:grid;gap:.5rem}
.wl-form label{font-family:var(--mono);font-size:var(--step--1);letter-spacing:.1em;text-transform:uppercase;color:var(--muted)}
.wl-form input{width:100%;background:var(--surface);border:1px solid var(--hairline);border-radius:var(--radius);padding:.95rem 1.05rem;min-height:48px;transition:border-color .3s,box-shadow .3s}
.wl-form input::placeholder{color:var(--muted);opacity:.65}
.wl-form input:focus{outline:none;border-color:var(--accent-line);box-shadow:0 0 0 4px var(--accent-soft)}
.wl-form .btn{flex:0 0 auto;align-self:end}
.wl-err{color:#ff7a7a;font-size:var(--step--1);min-height:1.2em}
.wl-status{font-family:var(--mono);font-size:var(--step--1);color:var(--accent-ink);min-height:1.4em;margin-top:var(--s2)}

/* The compact version, closing a template page or a guide. The .doc form of
   the heading rule outranks the prose h2 spacing a guide page applies. */
.wl-card{margin-top:var(--s5);padding:var(--s4) var(--s3);border:1px solid var(--hairline-2);border-radius:var(--radius-lg);background:radial-gradient(90% 140% at 50% 130%,var(--accent-soft),transparent 60%),var(--surface)}
.wl-card h2,.doc .wl-card h2{margin:0;font-size:var(--step-2);letter-spacing:-.03em;line-height:1.15}
.wl-card p.wl-sub{margin:.6rem 0 0;color:var(--muted);max-width:52ch}
.wl-card .wl-form{margin-top:var(--s3)}
.wl-card .wl-err,.wl-card .wl-status{margin-bottom:0}
.wl-wrap{padding-bottom:var(--s6)}
.wl-wrap .wl-card{margin-top:0}
