/* LLMnonsense — the entire visual skin lives in this file.
   Palette: Dopely #19 family for the chrome, one palette per track for the art.
   Type: Archivo, poster weights, tight tracking. */

:root{
  --paper:#FBFAF5;
  --panel:#F1EEE2;
  --line:#DCD8C8;
  --line-strong:#1C2410;
  --ink:#1C2410;
  --ink-soft:#44513A;
  --muted:#7E8873;
  --accent:#1E4F59;
  --accent-ink:#FBFAF5;
  --ok:#7EA00E;
  --lemon:#DCD964;
  --turq:#54C9CC;
  --bg:var(--paper);
  --sans:"Archivo","Helvetica Neue",Helvetica,Arial,sans-serif;
  --mono:"Archivo",ui-monospace,SFMono-Regular,monospace;
  /* The width this design was drawn to, and what the first version shipped
     with. .wrap already grows to it and stops, so there is nothing for a
     clamp to do here: the arithmetic was only earning its keep while the
     ceiling sat above this floor. */
  --max:1240px;
  --gutter:20px;
}
@media(min-width:900px){:root{--gutter:40px}}

*{box-sizing:border-box;margin:0;padding:0}
html{-webkit-text-size-adjust:100%}
body{background:var(--bg);color:var(--ink);font:400 16px/1.55 var(--sans);
  -webkit-font-smoothing:antialiased;overflow-x:hidden;display:flex;flex-direction:column;min-height:100vh}
a{color:inherit;text-decoration:none}
button{font:inherit;color:inherit;border:0;background:none;cursor:pointer}
img,svg{display:block}
[hidden]{display:none!important}
.wrap{max-width:var(--max);margin:0 auto;padding:0 var(--gutter);width:100%}
main{flex:1}
.mono{font-family:var(--mono)}
.dim{color:var(--muted)}

/* ── chrome ─────────────────────────────────────────── */
.topbar{border-bottom:1px solid var(--line);position:sticky;top:0;background:var(--bg);z-index:40}
.topbar .wrap{display:flex;align-items:center;gap:24px;height:62px}
.brand{font-weight:700;font-size:17px;letter-spacing:-.025em;white-space:nowrap;
  display:flex;align-items:center;gap:8px}
.brand span{color:var(--muted);font-weight:400}
/* The mark is a cut-out, not a tile: no border, no radius, no background. */
.brand-mark{width:28px;height:28px;flex:none}
.nav{display:flex;gap:26px;margin-left:auto;font-size:15.5px}
.nav a{color:var(--ink-soft);font-weight:500;padding:5px 0;letter-spacing:-.01em;
  border-bottom:2px solid transparent;white-space:nowrap}
.nav a:hover{color:var(--ink)}
.nav a[aria-current=page]{color:var(--ink);font-weight:600;border-bottom-color:var(--ink)}
.cart{font-size:14.5px;border:1px solid var(--line-strong);padding:7px 14px;white-space:nowrap;
  min-width:0;overflow:hidden;text-overflow:ellipsis}
.cart b{font-variant-numeric:tabular-nums}
.cart[aria-current=page]{background:var(--ink);color:var(--bg);border-color:var(--ink)}
.langs{display:flex;border:1px solid var(--line-strong);font:600 12px/1 var(--mono);letter-spacing:.07em}
.langs a{padding:7px 9px;color:var(--muted)}
.langs a+a{border-left:1px solid var(--line-strong)}
.langs a[aria-current]{background:var(--ink);color:var(--bg)}
/* A language the owner can see and visitors cannot. */
.langs a.lang-hidden{text-decoration:line-through}

.foot{border-top:1px solid var(--line);margin-top:72px;padding:28px 0 56px;font-size:14px;color:var(--ink-soft)}
.foot .wrap{display:flex;flex-wrap:wrap;justify-content:space-between;align-items:flex-start;gap:16px 40px}
.foot-who{display:flex;flex-direction:column;gap:6px;min-width:0}
.linkish{text-decoration:underline;color:inherit;padding:0}

/* ── type ───────────────────────────────────────────── */
h1{font-size:clamp(30px,5vw,50px);line-height:1.04;letter-spacing:-.035em;font-weight:700}
/* A heading that greets rather than titles. At full size the dashboard's is a
   sentence set in poster type, standing over the things it introduces. */
.h1-quiet{font-size:clamp(24px,3vw,34px);letter-spacing:-.03em}
h2{font-size:clamp(19px,2.4vw,25px);line-height:1.15;letter-spacing:-.025em;font-weight:650}
h3{font-size:17px;line-height:1.25;letter-spacing:-.018em;font-weight:600}
.kicker{font:500 11.5px/1 var(--mono);letter-spacing:.16em;text-transform:uppercase;color:var(--muted)}
.lede{font-size:clamp(16px,2vw,19px);color:var(--ink-soft);line-height:1.5}

/* ── buttons ────────────────────────────────────────── */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;
  padding:12px 20px;font-size:15px;font-weight:500;border:1px solid var(--line-strong);white-space:nowrap}
.btn-solid{background:var(--accent);color:var(--accent-ink)}
.btn-sm{padding:8px 14px;font-size:13.5px}
.btn:disabled{opacity:.45;cursor:default}

/* ── hero ───────────────────────────────────────────── */
.hero{padding:44px 0 0;border-bottom:1px solid var(--line)}
.hero-grid{display:grid;gap:26px;grid-template-columns:1fr;align-items:center}
/* The hole between the words and the picture was the text column growing
   while the text inside it could not: the column was a fraction of the page,
   the lede capped at 46 characters. Whatever the page gained, the gap took.

   The column is a fraction again, but the cap on the text is gone, so the
   two grow together and the gap stays the 48px the grid puts there. The
   picture keeps its 460px: past that it only makes the hero taller. */
@media(min-width:900px){
  .hero-grid{grid-template-columns:minmax(0,1fr) minmax(0,460px);gap:48px}
}
.hero h1{max-width:none}
.hero .lede{margin-top:18px;max-width:none}
.hero-cta{display:flex;gap:12px;flex-wrap:wrap;margin-top:26px}
.numbers{display:grid;grid-template-columns:repeat(2,1fr);border-top:1px solid var(--line);margin-top:40px}
@media(min-width:760px){.numbers{grid-template-columns:repeat(4,1fr)}}
.numbers div{padding:20px 18px 24px;border-right:1px solid var(--line);border-bottom:1px solid var(--line)}
@media(min-width:760px){.numbers div{border-bottom:0}}
/* Only while there are two columns. Unscoped it outweighed the rule that
   puts the border back at four — :nth-child beats a bare element selector —
   so the second cell lost its right edge and the divider between "tracks"
   and the price went missing. */
@media(max-width:759px){.numbers div:nth-child(2n){border-right:0}}
@media(min-width:760px){.numbers div{border-right:1px solid var(--line)}
  .numbers div:last-child{border-right:0}}
/* 26px is the size these are read at, and four figures never needed more.
   A word among them does: with the cheapest course given away the price cell
   says "Free–$49", "Gratis–$49" in Romanian, and at two cells to a phone that
   broke over two lines and stood the cell taller than the three beside it.
   So the row shrinks with the screen instead of wrapping, down to a floor
   that still fits the longest of them at 320px. 6vw passes 26px at about
   430px, so nothing below a small tablet is touched. */
.numbers b{display:block;font-size:clamp(21px,6vw,26px);letter-spacing:-.03em;white-space:nowrap}
.numbers span{display:block;font-size:12.5px;color:var(--muted);margin-top:4px}

/* ── rails (catalog) ────────────────────────────────── */
.track{padding:38px 0 8px}
.track-head{display:flex;align-items:baseline;gap:16px;padding-bottom:14px;border-bottom:1px solid var(--line)}
.track-head p{color:var(--muted);font-size:14.5px}
.track-head .count{margin-left:auto;font:400 12.5px/1 var(--mono);color:var(--muted);white-space:nowrap}
@media(max-width:760px){.track-head p{display:none}}
.rail{display:grid;grid-auto-flow:column;grid-auto-columns:78%;gap:16px;overflow-x:auto;
  scroll-snap-type:x mandatory;padding:20px var(--gutter) 24px;margin:0 calc(-1 * var(--gutter));
  scrollbar-width:none;-webkit-overflow-scrolling:touch}
.rail::-webkit-scrollbar{display:none}
@media(min-width:680px){.rail{grid-auto-columns:296px}}
@media(min-width:900px){
  .rail{margin:0;padding:20px 0 24px}
  /* Above a laptop the rail stops being a rail. Cards on a row sized to scroll
     left the row ending before the page did, under a rule that ran the whole
     width; as a grid they share it instead.

     auto-fill, not auto-fit: auto-fit collapses the columns it did not fill,
     so a track of three drew wider cards than a track of four and no two rows
     down the page matched. auto-fill keeps them, so the column count depends
     on the page and not on the track, and every card is the same width.

     And a column count that follows the width rather than a breakpoint: a
     fourth column arrives when a fourth card fits, so the cards grow with the
     window and give a little back when one more joins the row, instead of the
     page freezing and then lurching.

     270 rather than 296, so that four fit across the 1240 page: the widest
     track has four courses and now fills its row exactly. A fifth would need
     216px a card, which is narrower than the cover was drawn for. */
  .rail{grid-auto-flow:row;
    grid-template-columns:repeat(auto-fill,minmax(270px,1fr));
    gap:20px;overflow:visible;scroll-snap-type:none}
}

.card{scroll-snap-align:start;border:1px solid var(--line);display:flex;flex-direction:column;
  background:var(--bg);position:relative}
.card h3 a::after{content:"";position:absolute;inset:0;z-index:1}
.card-foot .btn{position:relative;z-index:2}
.card:hover{border-color:var(--line-strong)}
/* A course nobody can buy yet sits in grey, and takes its colour when the
   pointer lands on it. Only the picture is drained: the flag that says so and
   the words underneath stay as legible as on any other card. */
.card.soon .cover .art{filter:grayscale(1)}
.card.soon:hover .cover .art,.card.soon:focus-within .cover .art{filter:none}
.cover{position:relative;aspect-ratio:1/1}
.cover svg{position:absolute;inset:0;width:100%;height:100%}
.flag{position:absolute;top:10px;left:10px;font:500 10.5px/1 var(--mono);letter-spacing:.1em;
  text-transform:uppercase;padding:6px 8px;background:var(--bg);border:1px solid var(--line-strong)}
.flag.mine{background:var(--ink);color:var(--bg);border-color:var(--ink)}
.flag.go{background:var(--ok);color:#fff;border-color:var(--ok)}
.card-body{padding:16px;display:flex;flex-direction:column;gap:8px;flex:1}
.card-body .tag{color:var(--ink-soft);font-size:14.5px;flex:1}
.facts{font:400 12px/1 var(--mono);color:var(--muted)}
/* The free pill, on a catalog card (.freebie) and on a lesson row (.tagpill).
   Same green as the "available" flag, tinted down so it reads inside a card
   body or a table row instead of competing with the badge over the cover. */
.freebie,.tagpill{font:600 11.5px/1 var(--mono);letter-spacing:.07em;
  text-transform:uppercase;padding:6px 8px;white-space:nowrap;
  color:color-mix(in srgb,var(--ok) 68%,var(--ink));
  background:color-mix(in srgb,var(--ok) 13%,var(--bg));
  border:1px solid color-mix(in srgb,var(--ok) 42%,var(--bg))}
.freebie{align-self:flex-start}
.card-foot{display:flex;align-items:center;gap:10px;padding-top:13px;border-top:1px solid var(--line)}
.price{font-size:20px;font-weight:650;letter-spacing:-.025em;font-variant-numeric:tabular-nums}
.card-foot .btn{margin-left:auto}

/* ── bundles ────────────────────────────────────────── */
.bundles{display:grid;gap:0;border:1px solid var(--line);margin-top:20px;grid-template-columns:1fr}
@media(min-width:860px){.bundles{grid-template-columns:repeat(3,1fr)}}
.bundle{padding:24px;border-bottom:1px solid var(--line);display:flex;flex-direction:column;gap:8px}
@media(min-width:860px){.bundle{border-bottom:0;border-right:1px solid var(--line)}
  .bundle:last-child{border-right:0}}
.bundle:last-child{border-bottom:0}
.bundle.hot{background:var(--panel)}
.bundle p{color:var(--ink-soft);font-size:14.5px;flex:1}
.bundle-price{display:flex;align-items:baseline;gap:10px;margin-top:4px}
.bundle-price b{font-size:30px;letter-spacing:-.035em;font-variant-numeric:tabular-nums}
.bundle-price s{color:var(--muted);font-size:14px}
.bundle-price em{font-style:normal;font:500 11.5px/1 var(--mono);color:var(--ok)}

/* ── progress ───────────────────────────────────────── */
.bar{height:6px;background:var(--line);overflow:hidden}
.bar i{display:block;height:100%;width:100%;background:var(--t-deep,var(--ink));transform-origin:left center}
.bar-meta{display:flex;justify-content:space-between;font:400 12px/1 var(--mono);color:var(--muted);margin-top:8px}

/* ── section heads ──────────────────────────────────── */
.sec{display:flex;align-items:baseline;gap:16px;margin-top:48px;padding-bottom:12px;border-bottom:1px solid var(--line)}
.sec p{margin-left:auto;color:var(--muted);font-size:14px}

/* ── course page ────────────────────────────────────── */
.course-hero{padding:40px 0}
/* Three parts: the pitch, the buy box, the lesson plan. The plan is in the
   hero rather than in a section below it, because the hero is as tall as the
   buy box no matter what, and a plan underneath that started off-screen was a
   plan most readers never opened. Up here the free lessons are the first rows
   on the first screen, and the buy box sticks alongside the whole table.
   On a phone the order is pitch → plan → price: the rows anyone can open come
   before the price they have to weigh. The facts that used to sit here as a
   table are inside the buy box now. */
.course-grid{display:grid;gap:30px;grid-template-columns:1fr;position:relative}
@media(min-width:900px){
  .course-grid{grid-template-columns:1.6fr 1fr;column-gap:56px;row-gap:22px;
    grid-template-areas:"intro buy" "vitals buy" "plan buy";
    grid-template-rows:auto auto 1fr;align-items:start}
  .course-intro{grid-area:intro}
  .course-grid .course-side{grid-area:buy;position:sticky;top:82px}
  .course-grid .vitals{grid-area:vitals}
  .course-plan{grid-area:plan}
}
.vitals{display:flex;flex-wrap:wrap;gap:8px}
.vital{font:600 11.5px/1 var(--mono);letter-spacing:.07em;text-transform:uppercase;
  padding:7px 10px;border:1px solid var(--line-strong);color:var(--ink)}
.vital.lv-a{background:color-mix(in srgb,var(--ok) 15%,var(--bg));
  border-color:color-mix(in srgb,var(--ok) 45%,var(--bg));
  color:color-mix(in srgb,var(--ok) 68%,var(--ink))}
.vital.lv-b{background:color-mix(in srgb,var(--turq) 18%,var(--bg));
  border-color:color-mix(in srgb,var(--turq) 55%,var(--bg));
  color:color-mix(in srgb,var(--turq) 42%,var(--ink))}
.vital.lv-c{background:var(--accent);border-color:var(--accent);color:var(--accent-ink)}

/* The pitch reads at 52ch; the table is a table and takes the column. */
.course-plan .sec{margin-top:4px;padding-bottom:6px;border-bottom:0}
.course-extras{margin-top:52px}
.course-extras .sec{margin-top:0}
.course-extras .sec h2{font-size:18px;letter-spacing:-.02em}
.course-hero h1{font-size:clamp(27px,4.2vw,42px);margin-top:14px}
.course-hero .lede{margin-top:16px}
.promise{border-left:2px solid var(--ink);padding:4px 0 4px 16px;margin-top:24px}
.promise .kicker{margin-bottom:6px}

.course-side{display:grid;gap:18px;align-content:start}
.buybox{border:1px solid var(--line-strong);padding:18px}
/* Not drawn, only measured: see the fuse in page-course.js. */
.buy-fuse{position:absolute;top:0;left:0;width:1px;opacity:0;pointer-events:none}
/* Collapsed, the box is the course — its picture and its name — the price and
   the button. Everything that goes is given a height to shrink from, or there
   is nothing to animate. */
.buy-head{display:grid;grid-template-columns:1fr;gap:14px;align-items:center}
.buybox.compact .buy-head{grid-template-columns:95px 1fr}
.buy-thumb{position:relative;width:95px;height:95px;overflow:hidden;border:1px solid var(--line)}
.buy-thumb svg,.buy-thumb .art{position:absolute;inset:0;width:100%;height:100%}
.buy-id{display:grid;gap:6px;min-width:0}
/* Only the folded box names the course; open, the cover above has done it. */
.buy-thumb,.buy-name,.buy-tag{display:none}
.buybox.compact .buy-thumb,.buybox.compact .buy-name,.buybox.compact .buy-tag{
  display:block;animation:buy-in var(--dur-fold) var(--ease-fold) both}
@keyframes buy-in{from{opacity:0}to{opacity:1}}
.buy-name{font-size:16px;line-height:1.2;letter-spacing:-.02em;font-weight:700}
.buy-tag{font-size:13.5px;line-height:1.3;color:var(--ink-soft)}
/* Folded, it sits under the course's name where it belongs. Open, the name
   and the tagline are hidden and it is the only thing left in the row, which
   puts it under the cover — where it was before and where it reads fine. */
.buy-id .kicker{margin-top:2px}
.buybox .buy-cover{max-height:var(--fold-h,460px)}
.buybox .buy-note{font-size:13px}
.buybox .buy-cover,.buybox .bar,.buybox .bar-meta{
  transition:max-height var(--dur-fold) var(--ease-fold),
             opacity var(--dur-fold) var(--ease-fold),
             margin var(--dur-fold) var(--ease-fold),
             border-width var(--dur-fold) var(--ease-fold)}
.buybox.compact .buy-cover,.buybox.compact .bar,.buybox.compact .bar-meta{
  max-height:0;opacity:0;margin-top:0;margin-bottom:0;overflow:hidden;border-width:0}

/* The phone's buy bar. Desktop never sees it: there the price is pinned in
   its own column, and here there is no column to pin. It slides rather than
   appears, so it reads as arriving rather than as a repaint, and it reserves
   its own height at the foot of the page so it never sits over the footer. */
/* While the box is being measured nothing may ease: see measure() in
   page-course.js. */
.buybox.measuring .buy-cover,
.buybox.measuring .bar,.buybox.measuring .bar-meta{transition:none}

.buybar{position:fixed;left:0;right:0;bottom:0;z-index:50;display:none;
  align-items:center;gap:14px;padding:12px var(--gutter);
  padding-bottom:calc(12px + env(safe-area-inset-bottom));
  background:var(--bg);border-top:1px solid var(--line-strong);
  transform:translateY(100%);
  transition:transform 320ms var(--ease-out-expo)}
.buybar.up{transform:translateY(0)}
.buybar-price{font-size:25px;font-weight:650;letter-spacing:-.035em;
  font-variant-numeric:tabular-nums;white-space:nowrap}
.buybar-note{font-size:14px;color:var(--ink-soft)}
.buybar .btn{margin-left:auto;min-height:48px;padding-inline:26px}
@media(max-width:899px){
  .buybar{display:flex}
  body{padding-bottom:78px}
}

/* What else is for sale, stacked under the box. A catalog card cut to a row:
   picture, name, price, button — three of them cost ninety pixels each
   instead of five hundred, so the column does not outrun the lesson plan. */
.course-more{border:1px solid var(--line);padding:16px}
.course-more .kicker{color:var(--muted);font-size:12px;margin-bottom:12px}
.pick{display:grid;grid-template-columns:95px 1fr;gap:14px;
  padding:12px 0;border-top:1px solid var(--line);position:relative}
.pick h3 a::after{content:"";position:absolute;inset:0;z-index:1}
.pick-foot .btn{position:relative;z-index:2}
.course-more .kicker+.pick{border-top:0;padding-top:0}
.pick:last-child{padding-bottom:0}
/* Same as a card: grey until the pointer is on the row. */
.pick.soon .pick-art .art{filter:grayscale(1)}
.pick.soon:hover .pick-art .art,.pick.soon:focus-within .pick-art .art{filter:none}
.pick-art{position:relative;display:block;width:95px;height:95px;
  overflow:hidden;border:1px solid var(--line)}
.pick-art svg,.pick-art .art{position:absolute;inset:0;width:100%;height:100%}
.pick-body{display:flex;flex-direction:column;gap:6px;min-width:0}
.pick h3{font-size:14.5px;font-weight:600;line-height:1.25}
/* Two lines at most, so a long tagline cannot make one row twice its neighbour. */
.pick-tag{font-size:13px;line-height:1.35;color:var(--ink-soft);
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.pick-foot{display:flex;align-items:center;gap:10px;margin-top:auto}
.pick-price{font-size:15px;font-weight:650;font-variant-numeric:tabular-nums;white-space:nowrap}
/* Whatever ends the row goes to the right, button or not — so the words that
   replace the button land where the button was and read as its answer. */
.pick-foot>:last-child{margin-left:auto}
.buy-price{display:flex;align-items:center;gap:14px;flex-wrap:wrap}
.buybox .price{font-size:33px;display:block;letter-spacing:-.04em;line-height:1.05}
.buy-note{color:var(--muted);line-height:1.35}
.buybox .btn{width:100%;margin-top:12px}
.buybox ul{list-style:none;margin-top:13px;font-size:13.5px;color:var(--ink-soft);display:grid;gap:6px}
.buybox li::before{content:"— ";color:var(--muted)}
.buy-cover{aspect-ratio:15/14;border:1px solid var(--line);margin-bottom:14px;position:relative}
/* On a phone the square is a whole screen of picture, and it stands between
   the pitch and the price. Cropped to a band it still shows what the course
   looks like, and the price and the button come with it — the same trade the
   lesson figure makes above. */
@media(max-width:899px){.buy-cover{aspect-ratio:16/9}}
.buy-cover svg{position:absolute;inset:0;width:100%;height:100%}

.curric{border-top:1px solid var(--line-strong);margin-top:18px}
.lrow{display:grid;grid-template-columns:34px 1fr auto;gap:8px 14px;align-items:center;
  padding:14px 0;border-bottom:1px solid var(--line);position:relative}
.lrow h3 a::after{content:"";position:absolute;inset:0;z-index:1}
.lrow:last-child{border-bottom:0}
.lrow .num{font:400 12px/1 var(--mono);color:var(--muted)}
.lrow h3{font-size:16px;font-weight:600}
.lrow .sum{grid-column:2/-1;color:var(--ink-soft);font-size:14.5px;margin-top:3px;max-width:68ch}
.lrow .right{display:flex;align-items:center;gap:12px;font:400 12px/1 var(--mono);color:var(--muted)}
.lrow.locked h3{color:var(--muted)}
.lrow .done{width:18px;height:18px;border:1px solid var(--line-strong);display:grid;place-items:center;font-size:11px}
/* On a phone the badge, the minutes and the checks took so much of the row
   that the title broke over four lines. The plan is the first thing read here
   now, so the title gets the width and its meta drops under it. */
@media(max-width:620px){
  .lrow{grid-template-columns:26px 1fr;gap:6px 10px}
  .lrow .right{grid-column:2;justify-content:flex-start;gap:10px}
}
.lrow .done.on{background:var(--ink);color:var(--bg);border-color:var(--ink)}
/* .tagpill is styled with .freebie, up in the catalog section. */

/* ── lesson page ────────────────────────────────────── */
.lesson-wrap{display:grid;grid-template-columns:1fr;gap:0}
/* Capped and centred. The reading column is 720px wherever the window ends,
   so on a wide screen the pair used to sit against the left edge with most of
   the page empty beside it. Held together and centred instead, the margins
   are equal and the measure stays right for reading. */
@media(min-width:1000px){
  .lesson-wrap{grid-template-columns:286px minmax(0,1fr);max-width:1120px;margin:0 auto}
}
.lside{border-right:1px solid var(--line);padding:26px var(--gutter) 40px}
.lside-up{display:inline-flex;align-items:baseline;gap:8px;color:var(--muted)}
.lside-up:hover{color:var(--ink)}
@media(max-width:999px){.lside{border-right:0;border-bottom:1px solid var(--line);padding-bottom:22px}}
@media(min-width:1000px){.lside{position:sticky;top:62px;align-self:start;max-height:calc(100vh - 62px);overflow-y:auto}}
.lside ol{list-style:none;margin-top:14px;display:grid;gap:1px}
.lside a{display:grid;grid-template-columns:22px 1fr;gap:9px;padding:8px 9px;font-size:14px;color:var(--ink-soft);align-items:start}
.lside a:hover{background:var(--panel)}
.lside a[aria-current=page]{background:var(--t-dark,var(--ink));color:var(--bg)}
.lside a[aria-current=page] .n{color:var(--bg)}
.lside .n{font:400 11.5px/1.5 var(--mono);color:var(--muted)}
.lside a.locked{color:var(--muted)}
.lmain{padding:30px var(--gutter) 60px;min-width:0}
.lmain .inner{max-width:720px}
.lmain h1{font-size:clamp(25px,3.6vw,38px);margin-top:12px}
.lmain .sum{margin-top:16px;font-size:17.5px;line-height:1.6;color:var(--ink-soft)}
/* The one thing in a lesson that is a control rather than prose, and it used
   to be framed like every callout around it — read past, scrolled through,
   never ticked. A 2px ink frame and a reversed label give it the weight the
   finished-course panel already has: nothing else on the page looks like it,
   so it cannot be taken for more reading. */
.checklist{border:2px solid var(--t-dark,var(--ink));margin-top:38px;background:var(--bg)}
.checklist h2{font-size:13px;letter-spacing:.16em;text-transform:uppercase;font-family:var(--mono);
  font-weight:600;color:var(--bg);background:var(--t-dark,var(--ink));padding:12px 16px}
.checklist label{display:flex;gap:12px;align-items:flex-start;padding:13px 16px;
  border-bottom:1px solid var(--line);cursor:pointer;font-size:15.5px}
.checklist label:last-of-type{border-bottom:0}
.checklist input{width:18px;height:18px;margin-top:2px;flex:none;accent-color:var(--t-deep,var(--ink))}
.checklist label.on{color:var(--muted);text-decoration:line-through}
.outcome{border:1px solid var(--line);background:var(--panel);padding:18px 20px;margin-top:22px}
.outcome .kicker{margin-bottom:7px}
.lnav{display:flex;gap:12px;margin-top:34px;flex-wrap:wrap}

/* The two steps at the foot of a lesson. A .btn never wraps its text, which
   is right for a label like "Buy" but not for a lesson's name — two long ones
   could not fit side by side, so the row broke and one dropped under the
   other. Here they take half the row each and wrap their own titles instead.
   On a phone there is no half to take, so they stack. */
.lnav-steps{flex-wrap:nowrap;align-items:stretch}
.lnav-steps>*{flex:1 1 0;min-width:0}
.lnav-steps .btn{white-space:normal;text-align:center}
@media(max-width:619px){
  .lnav-steps{flex-direction:column}
  .lnav-steps>*{flex:0 0 auto}
  .lnav-steps .lnav-gap{display:none}
}
.paywall{border:1px solid var(--line-strong);padding:26px;margin-top:26px;background:var(--panel)}
.paywall h2{font-size:21px}
.paywall p{margin-top:9px;color:var(--ink-soft);max-width:52ch}

/* ── dashboard ──────────────────────────────────────── */
.kpis{display:grid;grid-template-columns:repeat(2,1fr);border:1px solid var(--line);margin-top:24px}
@media(min-width:760px){.kpis{grid-template-columns:repeat(4,1fr)}}
.kpis div{padding:18px;border-right:1px solid var(--line);border-bottom:1px solid var(--line)}
.kpis div:nth-child(2n){border-right:0}
.kpis div:nth-last-child(-n+2){border-bottom:0}
@media(min-width:760px){.kpis div{border-bottom:0}.kpis div:nth-child(2n){border-right:1px solid var(--line)}
  .kpis div:last-child{border-right:0}}
.kpis b{display:block;font-size:27px;letter-spacing:-.03em;font-variant-numeric:tabular-nums}
.kpis span{display:block;font-size:12.5px;color:var(--muted);margin-top:5px}
.mine-row{display:grid;grid-template-columns:1fr;gap:14px;border:1px solid var(--line);padding:14px;margin-top:14px}
@media(min-width:680px){.mine-row{grid-template-columns:120px 1fr 52px;align-items:center}}
.mine-row .cv{position:relative;height:78px}
.mine-row .cv svg{position:absolute;inset:0;width:100%;height:100%}
/* A course on the account page: the whole square cover, how far in they are,
   and the lesson they would open next. Its own grid rather than .mine-row's,
   which keeps a column for the dashboard's progress ring. */
.acc-row{display:grid;grid-template-columns:1fr;gap:16px;
  border:1px solid var(--line);padding:16px;margin-top:14px}
/* On the dashboard the rows follow the figures with no heading between them,
   so the first one opens the gap a heading used to. */
.kpis+.acc-row,.empty-art+.acc-row{margin-top:34px}
.acc-row .cv{position:relative;display:block;aspect-ratio:1/1;border:1px solid var(--line)}
/* On a phone the row is one column, and a cover as wide as the screen turns a
   list of courses into a scroll. */
@media(max-width:619px){.acc-row .cv{max-width:150px}}
.acc-row .cv svg{position:absolute;inset:0;width:100%;height:100%}
.acc-row h3{font-size:18px}
.acc-row .acc-tag{color:var(--ink-soft);font-size:14.5px;margin-top:5px;max-width:54ch}
.acc-row .acc-facts{font:400 12px/1 var(--mono);color:var(--muted);margin-top:10px}
.acc-next{border-left:2px solid var(--line-strong);padding:2px 0 2px 14px}
.acc-next .kicker{margin-bottom:5px}
.acc-next b{font-weight:600}

/* Two shapes above a phone. In the middle the picture stands beside the
   text and what to do next sits under it, still in the text column so it
   never lands under the picture. Given the width for a third column, where
   you stopped moves into it and the row becomes one line deep. */
@media(min-width:620px){
  .acc-row{grid-template-columns:168px 1fr;gap:18px 20px;align-items:start}
  .acc-row .cv{grid-row:1/span 2}
  .acc-next{grid-column:2}
}
@media(min-width:980px){
  .acc-row{grid-template-columns:200px 1fr 320px;gap:28px;align-items:center}
  .acc-row .cv{grid-row:1}
  .acc-next{grid-column:3;grid-row:1}
}

.empty{border:1px dashed var(--line-strong);padding:30px;margin-top:18px;color:var(--ink-soft)}

/* ── checkout ───────────────────────────────────────── */
.co-grid{display:grid;gap:30px;grid-template-columns:1fr;margin-top:26px}
@media(min-width:900px){.co-grid{grid-template-columns:1.6fr 1fr;gap:48px;align-items:start}}
/* Nothing in the second column means there is no second column. */
@media(min-width:900px){.co-grid.alone{grid-template-columns:1fr;max-width:780px}}
.ci{display:grid;grid-template-columns:72px 1fr auto;gap:16px;align-items:center;
  padding:16px 0;border-bottom:1px solid var(--line)}
.ci .cv{position:relative;height:54px;border:1px solid var(--line)}
.ci .cv svg{position:absolute;inset:0;width:100%;height:100%}
.ci .rm{font-size:13px;color:var(--muted);text-decoration:underline;grid-column:3;justify-self:end}
/* Not sticky: this box is the account's own facts in a single column, and
   stuck to the top it slid over everything scrolled up behind it. */
.summary{border:1px solid var(--line-strong);padding:22px}
/* Reading your details and changing your password are two errands, so they
   are two columns. Capped, because neither half reads better stretched: a
   line of facts across the full page is a hunt, and a wide text input invites
   a password nobody can check. */
/* Centred, not left-aligned: two columns of about 500px in a 1420px page sat
   against the left edge with the whole right half empty. */
.acc-grid{display:grid;gap:30px;grid-template-columns:1fr;max-width:1000px;margin-inline:auto}
/* The two halves name two equal things, so their headings are the same size
   and start on the same line. The left one is still the page's h1. No rule
   under either: each heading already has a bordered box beneath it, and the
   two lines together read as a box with a lid. */
.acc-grid .sec{margin-top:0;border-bottom:0;padding-bottom:14px}
/* .formcard carries a 22px top margin for the pages where it follows prose.
   Here it is the top of a column standing beside another box, and that margin
   was the whole reason the two started at different heights. */
.acc-grid .formcard{margin-top:0}
/* And the notice, when there is one, is what the column starts with. */
.acc-grid .notice{margin-top:0;margin-bottom:14px}
.acc-grid .sec h1{font-size:clamp(19px,2.4vw,25px);line-height:1.15;letter-spacing:-.03em}
@media(min-width:880px){.acc-grid{grid-template-columns:1fr 1fr;gap:44px;align-items:start}}

/* An owned course inside the facts box: thumbnail, title, count. Enough to
   recognise and click, nothing that competes with the box around it. */
.acc-line{display:grid;grid-template-columns:36px 1fr auto;gap:12px;align-items:center;
  padding:11px 0;border-top:1px solid var(--line);font-size:15px}
.acc-line .cv{position:relative;display:block;aspect-ratio:1/1;border:1px solid var(--line)}
.acc-line .cv svg{position:absolute;inset:0;width:100%;height:100%}
.acc-line .n{font:400 12px/1 var(--mono);color:var(--muted);white-space:nowrap}
.acc-line:hover .t{text-decoration:underline}
.acc-line.empty-line{display:block;color:var(--ink-soft);font-size:14.5px}
.summary .line{display:flex;justify-content:space-between;padding:8px 0;font-size:15px}
.summary .total{border-top:1px solid var(--line);margin-top:8px;padding-top:14px;
  font-size:22px;font-weight:650;letter-spacing:-.025em}
.notice{border:1px solid var(--line);background:var(--panel);padding:14px 16px;margin-top:16px;
  font-size:13.5px;color:var(--ink-soft)}
/* An account with no password yet is something to do, not a footnote. It
   borrows the forms' own red so the site has one colour for "see to this". */
.notice.warn{background:#F7EFEA;border-color:#8C4A4A;color:#8C4A4A}

/* Real artwork drops in over the drawn placeholder. */
.cover,.cv,.buy-cover{overflow:hidden}
.art{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}

/* Poster typography */
body{font-family:var(--sans);font-weight:420}
h1,h2,h3,.price,.numbers b,.kpis b,.bundle-price b{font-weight:800}
h1{letter-spacing:-.04em}
h2{letter-spacing:-.03em}
.kicker{font-weight:700;letter-spacing:.14em}
.brand{font-weight:800;letter-spacing:-.04em;font-size:19px}
.btn{font-weight:600}
.flag{font-weight:700}

/* Slots that stay empty until the illustrations are dropped into art/ */
/* The lesson leads with words; the drawing sits beside them, not over them.

   The picture keeps its frame. It was taken off and looked at without one:
   the felt then lies straight on the page, which is what PROMPTS-ready.md
   asks a page illustration to do, but only where the picture's own ground
   matches the paper closely. Across the two courses it does not always —
   telegram-agent's art predates that rule and sits about 11/13/23 below
   #FBFAF5 — so without a frame the shop would have one course with
   illustrations that sink in and one with cream squares on the page. The
   frame makes both read the same, and it is a 1px line of --line, the same
   rule the shop divides everything else with. */
.lesson-head{display:grid;gap:20px;grid-template-columns:1fr;align-items:start}
@media(min-width:880px){.lesson-head{grid-template-columns:1fr 306px;gap:32px}}
/* Only the header's title column shares this grid — the lesson body is full
   width below it — so the picture can take its width without costing anyone a
   narrower read.

   Beside the title the picture starts one title-line down, level with the
   second line rather than the first, which stops the two columns reading as
   one slab. The offset is the title's own line — `.lmain h1` sizes it with
   that clamp and h1 carries line-height 1.04 — plus the 12px of margin the
   h1 has and the picture does not. Written out rather than typed as a number
   so it keeps step with the title at every width. */
.lesson-fig{width:100%;height:auto;border:1px solid var(--line)}
@media(min-width:880px){
  .lesson-fig{margin-top:calc(12px + 1.04 * clamp(25px,3.6vw,38px))}
}
@media(max-width:879px){.lesson-fig{aspect-ratio:16/7;object-fit:cover;object-position:center}}
.hero-art{width:100%;height:auto;max-width:460px;justify-self:center}

/* ── lesson body ────────────────────────────────────── */
.body{margin-top:26px}
.body>*+*{margin-top:18px}
.b-h{font-size:21px;letter-spacing:-.025em;margin-top:34px!important}
.b-p{font-size:17px;line-height:1.62;color:var(--ink-soft)}
.b-list{padding-left:22px;font-size:17px;line-height:1.62;color:var(--ink-soft)}
.b-list li+li{margin-top:7px}
.b-list li::marker{color:var(--muted)}

.b-cmd{border:2px solid var(--line-strong);background:var(--ink)}
.b-cmd figcaption{display:flex;align-items:center;gap:10px;padding:9px 12px;
  background:var(--line-strong);color:var(--paper);font-size:13px;font-weight:600}
.b-cmd figcaption em{font-style:normal;font-weight:400;opacity:.7;font-size:12.5px}
.b-cmd .copy{margin-left:auto;border:1px solid rgba(251,250,245,.4);color:var(--paper);
  padding:4px 10px;font-size:12px;font-weight:600}
.b-cmd .copy:hover{background:rgba(251,250,245,.14)}
.b-cmd pre{margin:0;padding:14px 16px;overflow-x:auto;color:var(--lemon);
  font:400 13.5px/1.7 ui-monospace,SFMono-Regular,Menlo,monospace;-webkit-overflow-scrolling:touch}

.b-note,.b-expect{display:grid;gap:5px;padding:16px 18px;background:var(--panel);
  border:1px solid var(--line-strong);border-radius:3px}
.b-note.warn{border-color:#8C4A4A;background:#F7EFEA}
/* Tinted rather than given the track's own paper: four of the five papers sit
   within a shade of the shop's, so the panel would stop being a panel. The
   mix is the same one .vital uses, so the two agree. */
.b-expect{border-color:var(--t-deep,var(--ok));
  background:color-mix(in srgb,var(--t-deep,var(--ok)) 11%,var(--bg))}
.b-note strong,.b-expect strong{font-size:13px;letter-spacing:.08em;text-transform:uppercase}
.b-note.warn strong{color:#8C4A4A}
.b-expect strong{color:var(--t-deep,var(--ok))}
.b-note span,.b-expect span{font-size:15.5px;color:var(--ink-soft);line-height:1.55}

.b-img{border:1px solid var(--line)}
.b-img img{width:100%;height:auto}
.b-img figcaption{padding:9px 12px;font-size:13px;color:var(--muted);border-top:1px solid var(--line)}

.b-table{overflow-x:auto;border:1px solid var(--line)}
.b-table table{border-collapse:collapse;width:100%;font-size:15px}
.b-table th,.b-table td{text-align:left;padding:10px 13px;border-bottom:1px solid var(--line)}
.b-table th{background:var(--panel);font-weight:700}

.b-quote{border-top:2px solid var(--line-strong);padding-top:16px;font-size:20px;line-height:1.45;
  max-width:60ch;font-style:italic}
.b-quote cite{display:block;margin-top:8px;font-size:14px;font-style:normal;color:var(--muted)}

.b-stats{display:grid;gap:1px;background:var(--line);border:1px solid var(--line);
  grid-template-columns:repeat(auto-fit,minmax(150px,1fr))}
.b-stats div{background:var(--paper);padding:16px}
.b-stats b{display:block;font-size:26px;letter-spacing:-.03em}
.b-stats span{display:block;font-size:14px;margin-top:4px}
.b-stats em{display:block;font-style:normal;font-size:12px;color:var(--muted);margin-top:6px}

/* ── course extras ──────────────────────────────────── */
.extras{border-top:1px solid var(--line-strong)}
.extras details{border-bottom:1px solid var(--line)}
.extras summary{display:flex;flex-wrap:wrap;align-items:baseline;gap:12px;padding:16px 0;cursor:pointer;list-style:none}
.extras summary::-webkit-details-marker{display:none}
.extras summary::before{content:"+";font-weight:800;width:16px}
.extras details[open] summary::before{content:"\2013"}
.extras summary strong{font-size:17px}
.extras summary span{color:var(--muted);font-size:14.5px}
.locked-note{padding:0 0 16px 28px;font-size:14.5px}
.gloss{padding:0 0 22px 28px;display:grid;gap:14px;max-width:70ch}
.gloss dt{font-weight:700;font-size:15.5px}
.gloss dd{margin:3px 0 0;display:grid;gap:3px}
.gloss .plain{font-size:15.5px;color:var(--ink-soft)}
.gloss .precise{font-size:14px;color:var(--muted)}
.appx{padding:0 0 22px 28px;max-width:70ch}
.appx h3{font-size:16px;margin-bottom:8px}
.appx ul{padding-left:20px;display:grid;gap:6px;font-size:15.5px;color:var(--ink-soft)}

/* ── track badges ───────────────────────────────────── */
.badge{width:46px;height:46px;flex:none;border:1px solid var(--line);object-fit:cover}
.badge-sm{width:30px;height:30px}
.track-head{align-items:center}
.track-head h2{margin-right:2px}
.track-line{display:flex;align-items:center;gap:10px}
@media(max-width:620px){.badge{width:38px;height:38px}}

/* ── pictures for the empty and the finished states ─── */
.empty-art{display:grid;gap:18px;justify-items:center;text-align:center;padding:26px 20px 30px}
.empty-art img{width:100%;max-width:420px;height:auto}
.done-panel{border:2px solid var(--line-strong);margin-top:30px;display:grid;grid-template-columns:1fr}
@media(min-width:680px){.done-panel{grid-template-columns:260px 1fr;align-items:center}}
.done-panel img{width:100%;height:auto;display:block;border-bottom:1px solid var(--line)}
@media(min-width:680px){.done-panel img{border-bottom:0;border-right:1px solid var(--line)}}
.done-panel>div{padding:22px}
.done-panel p{margin-top:8px;color:var(--ink-soft);font-size:15.5px}

/* ── new title and meta shapes, after the eyebrows came out ─────── */
.title-row{display:flex;gap:18px;align-items:flex-start}
.title-row .badge{width:95px;height:95px;margin-top:2px}
@media(max-width:620px){.title-row .badge{width:58px;height:58px}}
.track-name{margin-top:8px;font-size:14px;font-weight:600;letter-spacing:.09em;
  text-transform:uppercase;color:var(--muted)}
.lesson-meta{margin-top:10px;font-size:13px;font-weight:600;letter-spacing:.1em;
  text-transform:uppercase;color:var(--muted)}

/* ── the parts the browser draws, drawn by us ───────────────────── */
::selection{background:var(--lemon);color:var(--ink)}
html{caret-color:var(--accent);scrollbar-color:var(--line-strong) var(--panel)}
:focus-visible{outline:2px solid var(--accent);outline-offset:3px;border-radius:2px}
.price,.numbers b,.kpis b,.dstats b,.bundle-price b,.summary .total,.bar-meta,.facts{
  font-variant-numeric:tabular-nums}
::-webkit-scrollbar{width:12px;height:12px}
::-webkit-scrollbar-track{background:var(--panel)}
::-webkit-scrollbar-thumb{background:var(--line-strong);border:3px solid var(--panel);border-radius:8px}

/* ── motion ──────────────────────────────────────────────────────
   One idea, applied consistently: a card rests a little withdrawn and
   steps forward under the pointer, while the rest of its shelf steps back.
   Exponential ease-out from a visible default; nothing animates on load. */
:root{
  --ease-out-expo:cubic-bezier(.16,1,.3,1);
  --ease-fold:cubic-bezier(.33,1,.68,1);
  --dur-lift:380ms;
  --dur-art:560ms;
  --dur-fold:880ms;
}

.card{
  opacity:.94;
  transform:translateY(0);
  box-shadow:0 0 0 rgba(28,36,16,0);
  transition:opacity var(--dur-lift) var(--ease-out-expo),
             transform var(--dur-lift) var(--ease-out-expo),
             border-color var(--dur-lift) var(--ease-out-expo),
             box-shadow var(--dur-lift) var(--ease-out-expo);
}
.card .cover{overflow:hidden}
/* A row is not a card, so it does not lift or cast a shadow — but the picture
   can do what a card's does. The greyscale keeps its own quicker fade; the
   zoom takes the slow one the covers use everywhere. */
.pick-art .art,.pick-art svg{
  transition:transform var(--dur-art) var(--ease-out-expo),
             filter 320ms var(--ease-out-expo);
}
.card .cover .art,.card .cover svg{
  transition:transform var(--dur-art) var(--ease-out-expo),
             filter var(--dur-art) var(--ease-out-expo);
  filter:saturate(.92);
}

@media(hover:hover) and (pointer:fine){
  .card:hover{
    opacity:1;
    transform:translateY(-8px);
    border-color:var(--line-strong);
    box-shadow:0 14px 34px -18px rgba(28,36,16,.45);
  }
  .card:hover .cover .art,.card:hover .cover svg{transform:scale(1.045);filter:saturate(1)}

  /* the shelf you are reading recedes around the card you are on */
  .rail:hover .card:not(:hover){opacity:.62}

  .mine-row,.lrow,.ci{transition:background var(--dur-lift) var(--ease-out-expo)}
  .card.soon .cover .art{transition:filter 320ms var(--ease-out-expo)}
  .pick{transition:background var(--dur-lift) var(--ease-out-expo)}
  .pick:hover{background:var(--panel)}
  .pick:hover .pick-art .art,.pick:hover .pick-art svg{transform:scale(1.045)}
  .mine-row:hover,.ci:hover{background:var(--panel)}

  .btn{transition:transform 180ms var(--ease-out-expo),
                  background 180ms var(--ease-out-expo),
                  color 180ms var(--ease-out-expo)}
  .btn:hover{transform:translateY(-2px)}
  .btn-solid:hover{background:var(--ink)}
  .badge{transition:transform var(--dur-lift) var(--ease-out-expo)}
  .track-head:hover .badge{transform:rotate(-3deg) scale(1.06)}
}
.btn:active{transform:translateY(0) scale(.985)}

/* a checkpoint is the one place a tick deserves a beat of its own */
.checklist label{transition:background 240ms var(--ease-out-expo),
                            color 240ms var(--ease-out-expo)}
.checklist label:hover{background:var(--panel)}
.bar i{transition:transform 620ms var(--ease-out-expo)}

@media(prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms!important;animation-iteration-count:1!important;
    transition-duration:.01ms!important;scroll-behavior:auto!important}
  .card{opacity:1}
  .rail:hover .card:not(:hover){opacity:1}
}

/* On a phone the lesson list folds away, so the lesson itself starts at the top.
   From the sidebar breakpoint up it is always open and the toggle disappears. */
.lesson-list summary{display:flex;align-items:center;gap:10px;margin-top:14px;padding:11px 12px;
  border:1px solid var(--line-strong);cursor:pointer;list-style:none;
  font-size:13px;font-weight:700;letter-spacing:.09em;text-transform:uppercase}
.lesson-list summary::-webkit-details-marker{display:none}
.lesson-list summary::after{content:"+";margin-left:auto;font-size:16px}
.lesson-list[open] summary::after{content:"\2013"}
@media(min-width:1000px){
  .lesson-list summary{display:none}
}

/* ── chrome on a phone ──────────────────────────────── */
/* Brand, two nav links, the language switcher and the cart share one 62px bar.
   Romanian labels are the longest, so the chrome gives up its decoration
   before any link gives up its words. */
@media(max-width:620px){
  .topbar .wrap{gap:12px}
  .brand span{display:none}
  .brand{gap:7px}
  .brand-mark{width:24px;height:24px}
  .nav{gap:12px;font-size:13px}
  .langs{font-size:11px}
  .langs a{padding:6px 6px}
  .cart{padding:6px 9px;font-size:13px;max-width:40vw}
}
@media(max-width:430px){
  .topbar .wrap{gap:8px}
  .brand{font-size:15px;gap:6px}
  .brand-mark{width:22px;height:22px}
  /* The smallest phones drop the Catalog link — the logo already goes there. */
  .nav-home{display:none}
  .nav{gap:8px;font-size:12px}
  .langs{font-size:10px}
  .langs a{padding:6px 5px}
  .cart{padding:5px 7px;font-size:12px}
}

/* ── forms ──────────────────────────────────────────── */
/* There was not a single text input on the site until it grew accounts, so
   these are the first. Same language as everything else: a hard border, no
   radius, the ink colour for focus rather than a glow. */
.formwrap{max-width:460px;margin:0 auto;padding-bottom:40px}
.formwrap h1{font-size:clamp(26px,3.6vw,36px)}
.formwrap .lede{margin-top:10px}
.formcard{border:1px solid var(--line-strong);padding:22px;margin-top:22px;
  display:flex;flex-direction:column;gap:16px;background:var(--bg)}
.field{display:flex;flex-direction:column;gap:6px}
/* :not(.pw) so the rule stays on the label and off the wrapper that holds the
   input and its reveal button, which is also a direct child span. */
.field>span:not(.pw){font:500 13px/1 var(--sans);letter-spacing:-.01em;color:var(--ink-soft)}
.field>em{font-size:12.5px;color:var(--muted);font-style:normal}
.field input{font:400 16px/1.3 var(--sans);color:var(--ink);background:var(--bg);
  border:1px solid var(--line);padding:12px 13px;width:100%;appearance:none;border-radius:0}
.field input:hover{border-color:var(--ink-soft)}
.field input:focus{outline:0;border-color:var(--line-strong);box-shadow:inset 0 0 0 1px var(--line-strong)}
/* :user-invalid, not :invalid — an empty required field is not a mistake
   until somebody has actually tried to leave it empty. */
.field input:user-invalid{border-color:#8C4A4A}
.field input[type=password]{font-family:var(--mono);letter-spacing:.06em}

/* A password field with a button to reveal it. The mono face is pinned to the
   wrapper, not to type=password, so revealing the text does not reflow it. */
.pw{position:relative;display:block}
.pw input{padding-right:48px;font-family:var(--mono);letter-spacing:.06em}
.pw-eye{position:absolute;right:1px;top:1px;bottom:1px;width:46px;padding:0;border:0;
  background:transparent;color:var(--muted);cursor:pointer;display:grid;place-items:center}
.pw-eye:hover{color:var(--ink)}
.pw-eye svg{width:20px;height:14px;fill:none;stroke:currentColor;stroke-width:1.4;
  stroke-linecap:round;stroke-linejoin:round}
/* What was just bought, on the page that follows paying for it. The picture
   is square because that is the shape it was drawn in — the landscape crop
   used in a list throws away a third of it, and here there is room. */
.wcourse{display:grid;grid-template-columns:1fr;gap:16px;
  border:1px solid var(--line);padding:16px}
@media(min-width:560px){.wcourse{grid-template-columns:190px 1fr;gap:20px;align-items:start}}
.wcourse-art{position:relative;display:block;aspect-ratio:1/1;border:1px solid var(--line)}
.wcourse-art svg{position:absolute;inset:0;width:100%;height:100%}
.wcourse-tag{color:var(--ink-soft);font-size:15px;margin-top:5px}
.wcourse-promise{margin-top:16px}
.wcourse-facts{font:400 13px/1 var(--mono)}
/* What the course asks of you and the way into it, on one line: the facts
   read as a caption to the button rather than as another paragraph above it. */
.wcourse-foot{display:flex;align-items:center;gap:16px;flex-wrap:wrap;margin-top:18px}
.wcourse-foot .btn{margin-left:auto}

/* .formcard carries a top margin for the pages where it follows prose. Here
   it is the top of a column standing beside the course, and that margin was
   the whole of the difference in where the two started. */
.co-grid .formcard{margin-top:0}

.formerr,.formok{font-size:14px;padding:11px 13px;border:1px solid var(--line-strong)}
.formerr{background:#F7EFEA;color:#8C4A4A;border-color:#8C4A4A}
.formok{background:var(--panel)}

/* ── the stand-in checkout ──────────────────────────── */
/* A payment page belongs to whoever takes the money, so this one wears none of
   the shop's chrome: no header, no footer, nothing to click away to. */
.payshell{background:var(--panel);display:flex;align-items:center;justify-content:center;
  padding:28px var(--gutter)}
.paycard{flex:0 1 420px;background:var(--bg);border:1px solid var(--line-strong);padding:26px}
.paybrand{font:500 11.5px/1 var(--mono);letter-spacing:.16em;text-transform:uppercase;
  color:var(--muted);padding-bottom:16px;border-bottom:1px solid var(--line)}
.payline{display:flex;align-items:flex-start;gap:16px;padding:18px 0;border-bottom:1px solid var(--line)}
.payline div{flex:1;display:flex;flex-direction:column;gap:3px}
.payline strong{font-weight:600;letter-spacing:-.015em}
.payline span{font-size:13.5px;color:var(--muted)}
.payline b{font-size:23px;font-weight:700;letter-spacing:-.03em;font-variant-numeric:tabular-nums}
.paycard form{display:flex;flex-direction:column;gap:16px;padding-top:20px}
.paynote{margin-top:18px;font-size:12.5px;line-height:1.5;color:var(--muted);
  border-top:1px solid var(--line);padding-top:14px}

/* ── footer links ───────────────────────────────────── */
/* Terms, refunds and a working support address are not decoration: a payment
   provider checks they are reachable before it will take money. */
.foot-links{display:flex;flex-wrap:wrap;gap:4px 18px}
.foot-links a{text-decoration:underline;text-decoration-color:var(--line)}
.foot-links a:hover{text-decoration-color:currentColor}

/* ── long prose ─────────────────────────────────────── */
/* The legal pages, which are read rarely and must be readable when they are. */
.prose{max-width:66ch;padding-bottom:40px}
.prose h1{font-size:clamp(26px,3.6vw,38px)}
.prose h2{margin-top:34px}
.prose h3{margin-top:22px;font-size:17px;font-weight:600}
.prose p,.prose li{color:var(--ink-soft);margin-top:12px}
.prose ul,.prose ol{margin-top:10px;padding-left:22px}
.prose li{margin-top:6px}
.prose a{text-decoration:underline}
.prose .updated{font:500 11.5px/1 var(--mono);letter-spacing:.14em;text-transform:uppercase;
  color:var(--muted);margin-top:14px}
/* A table inside prose — the privacy page lists what is stored in one. */
.prose table{width:100%;border-collapse:collapse;margin-top:16px;font-size:14.5px;display:block;overflow-x:auto}
.prose th,.prose td{text-align:left;padding:10px 12px;border:1px solid var(--line);vertical-align:top}
.prose th{background:var(--panel);font-weight:600;white-space:nowrap}
.prose code{font-family:var(--mono);font-size:13px;background:var(--panel);padding:1px 4px}

/* ── the one question asked before paying ───────────── */
/* A native <dialog>, so the page behind it goes inert and Escape closes it
   without a line of script. It holds a single field: where the course should
   go. The card details are the payment provider's business, not ours. */
/* margin:auto is what centres a modal <dialog>, and the reset at the top of
   this file takes it away from everything — so it is put back by hand here. */
.ask{border:1px solid var(--line-strong);padding:0;background:transparent;margin:auto;
  max-width:430px;width:calc(100% - 2*var(--gutter))}
.ask::backdrop{background:rgba(28,36,16,.45)}
.ask .formcard{margin:0;border:0}
.ask h2{font-size:21px}
.ask .dim{font-size:13.5px;margin-top:-4px}
.askrow{display:flex;gap:10px}
.askrow .btn{flex:1;justify-content:center}
