/* ============================================================
   Tavla — the brand pages (/, /blog/, /support)
   Loaded AFTER styles.css, which still owns the fonts, the tokens,
   the buttons, the newsletter form, the scribbles and the cookie
   banner. This file is the sheet: a ruled grid, labels in the pixel
   face, one display moment per row, one stamp per screen.

   The look, from the 2026-09-09 brief: modern and utilitarian. A
   printed spec sheet rather than a landing page. Hairlines do the
   layout; colour is rationed (orange = the stamp, blue = the
   highlight); the two inks are allowed to run to paper as gradients,
   with grain on them; pixel art where something is drawn.
   ============================================================ */

:root,
:root[data-theme="light"] {
  --rule:      rgba(23, 22, 20, 0.14);     /* the grid lines, a touch firmer than --hairline */
  --rule-2:    rgba(23, 22, 20, 0.07);     /* the fine grid behind a figure */
  --grain-op:  .16;
  --grain-blend: multiply;
  --wash-blue: #e4e6f5;                    /* the coach card's light blue, for a tint */
}
:root[data-theme="dark"] {
  --rule:      rgba(242, 240, 234, 0.16);
  --rule-2:    rgba(242, 240, 234, 0.07);
  --grain-op:  .22;
  --grain-blend: screen;
  --wash-blue: #1d2247;
}

html { scroll-padding-top: 64px; }
body.brand { font-size: 16px; }

/* ---------- Type roles ---------- */
.lab {
  font-family: "Geist Pixel", ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: .68rem; letter-spacing: .12em; text-transform: uppercase; line-height: 1.4;
  color: var(--muted);
}
.lab .n { color: var(--fg); }
.lab.stamp { color: var(--accent); }
.display {
  font-family: "Clash Display", ui-sans-serif, system-ui, sans-serif;
  font-weight: 600; letter-spacing: -0.015em; line-height: 1.02;
}
.serif {
  font-family: ui-serif, "New York", "Iowan Old Style", Charter, Georgia, serif;
  font-weight: 400; letter-spacing: 0; line-height: 1.2;
}
.pix { font-family: "Geist Pixel", ui-monospace, SFMono-Regular, Menlo, monospace; font-variant-numeric: tabular-nums; }
.body { color: var(--muted); line-height: 1.55; }
.body strong { color: var(--fg); font-weight: 600; }
.body p + p { margin-top: .8em; }
.arrow-link { color: var(--fg); text-decoration: none; border-bottom: 1px solid var(--rule); padding-bottom: .1em; }
.arrow-link:hover { border-color: var(--fg); }
.paren { color: var(--muted); text-decoration: none; }
.paren:hover { color: var(--fg); }

/* ---------- The masthead: one thin strip ---------- */
.mast {
  position: sticky; top: 0; z-index: 20;
  display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 1.5rem;
  padding: .75rem clamp(1rem, 3vw, 2rem);
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--rule);
}
.mast .wordmark { font-size: 1.25rem; }
.mast-line { text-align: center; }
@media (max-width: 760px) { .mast-line { display: none; } .mast { grid-template-columns: auto 1fr; } .mast-nav { justify-self: end; } }
.mast-nav { display: flex; align-items: center; gap: 1.1rem; }
.mast-nav a.lab { text-decoration: none; }
.mast-nav a.lab:hover { color: var(--fg); }
.mast-nav a.lab.is-here { color: var(--fg); }
.mast-nav .theme-toggle { width: 32px; height: 32px; }
.mast-nav .theme-toggle svg { width: 16px; height: 16px; }
@media (max-width: 560px) { .mast-nav a.lab:not(.keep) { display: none; } }

/* ---------- The sheet ---------- */
.sheet { width: 100%; }
.row {
  display: grid; grid-template-columns: repeat(12, minmax(0, 1fr));
  border-bottom: 1px solid var(--rule);
}
.cell { padding: clamp(1.1rem, 2.6vw, 2.6rem); border-left: 1px solid var(--rule); min-width: 0; }
.cell:first-child { border-left: 0; }
.cell.tight { padding: .75rem clamp(1.1rem, 2.4vw, 2rem); }
.cell.tall { padding-top: clamp(2.2rem, 5vw, 4.5rem); padding-bottom: clamp(2.2rem, 5vw, 4.5rem); }
.cell.flush { padding: 0; }
.c1 { grid-column: span 1; } .c2 { grid-column: span 2; } .c3 { grid-column: span 3; }
.c4 { grid-column: span 4; } .c5 { grid-column: span 5; } .c6 { grid-column: span 6; }
.c7 { grid-column: span 7; } .c8 { grid-column: span 8; } .c9 { grid-column: span 9; }
.c10 { grid-column: span 10; } .c12 { grid-column: span 12; }

/* Under 900 the sheet is one column; every cell gets its own rule on top. */
@media (max-width: 900px) {
  .row { grid-template-columns: 1fr; }
  .cell, .c1, .c2, .c3, .c4, .c5, .c6, .c7, .c8, .c9, .c10, .c12 { grid-column: 1 / -1; border-left: 0; border-top: 1px solid var(--rule); }
  .cell:first-child { border-top: 0; }
  .row.keep-two { grid-template-columns: 1fr 1fr; }
  .row.keep-two .cell { border-top: 0; }
  .row.keep-two .cell + .cell { border-left: 1px solid var(--rule); }
  .hide-narrow { display: none; }
}

/* The spec strip under the masthead, and the same shape in the footer. */
.strip { display: flex; flex-wrap: wrap; gap: .4rem 2rem; }
.strip .lab { white-space: nowrap; }

/* ---------- The bands: the binder ----------
   Every section opens with a band that sticks under the masthead and stays there while
   the rest of the page scrolls beneath it, so by the foot of the page the seven bands sit
   piled like the tabs of a binder. They are direct children of .stack, not of their
   sections, which is what lets them keep sticking after their own content has gone.
   --i is the band's index; --band its height. On phones they share one offset and
   replace each other instead of piling. */
.stack { --band: 56px; --mast: 57px; position: relative; }   /* --mast is re-measured by brand.js */
.band {
  position: sticky; top: calc(var(--mast) + var(--i, 0) * var(--band)); z-index: 10;
  display: grid; grid-template-columns: 5rem 1fr auto; align-items: center; gap: 1.5rem;
  height: var(--band); padding: 0 clamp(1.1rem, 2.6vw, 2.6rem);
  background: var(--bg); color: var(--fg);
  border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule);
  scroll-margin-top: calc(var(--mast) + var(--i, 0) * var(--band));
}
.band .name { font-family: "Clash Display", ui-sans-serif, system-ui, sans-serif; font-weight: 600; font-size: 1.25rem; letter-spacing: -0.01em; line-height: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.band .num { color: var(--muted); }
.band .note { color: var(--muted); text-align: right; }
.band-2 { background: var(--bg-2); }
.band-stamp { background: var(--stamp); color: var(--stamp-ink); }
.band-stamp .num, .band-stamp .note { color: var(--stamp-ink); opacity: .7; }
.band-blue { background: var(--wash-blue); }
:root[data-theme="dark"] .band-blue { color: var(--fg); }
@media (max-width: 900px) {
  .stack { --band: 48px; }
  .band { top: var(--mast); grid-template-columns: 3.6rem 1fr; gap: 1rem; }
  .band .note { display: none; }
  .band .name { font-size: 1.05rem; }
}
@media (max-width: 560px) { .band { grid-template-columns: 3rem 1fr; } }
@media (prefers-reduced-motion: reduce) { .band { position: static; } }

/* ---------- Row labels ---------- */
.rowlab { display: flex; flex-direction: column; justify-content: space-between; gap: 1.5rem; }
.rowlab .lab .n { display: block; font-size: 1rem; margin-bottom: .3rem; }
.rowlab .foot { color: var(--muted); }
@media (max-width: 900px) { .cell.tall.rowlab { padding-top: 1.1rem; padding-bottom: 1.1rem; } }

/* ---------- Hero ---------- */
.hero-cell { display: flex; flex-direction: column; justify-content: space-between; gap: clamp(2rem, 5vw, 4rem); }
.hero-title { font-size: clamp(2.5rem, 6.6vw, 6.4rem); max-width: 11ch; margin: 0; }
.hero-title .underlined .scribble { bottom: -0.16em; height: .3em; }
.hero-lede { font-size: clamp(1.02rem, 1.4vw, 1.2rem); max-width: 40ch; }
.hero-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 1.2rem 1.6rem; margin-top: 1.6rem; }
.hero-actions .btn-primary { background: var(--stamp); color: var(--stamp-ink); border-radius: 12px; }

/* The figure: the pixel lock on the orange running to paper, on a fine grid, with grain. */
.fig {
  position: relative; overflow: hidden; min-height: 460px; height: 100%;
  display: grid; place-items: center;
  background:
    linear-gradient(var(--rule-2) 1px, transparent 1px) 0 0 / 24px 24px,
    linear-gradient(90deg, var(--rule-2) 1px, transparent 1px) 0 0 / 24px 24px,
    linear-gradient(180deg, var(--stamp) 0%, color-mix(in srgb, var(--stamp) 55%, var(--bg)) 42%, var(--bg) 100%);
}
.fig-blue, :root[data-theme="dark"] .fig-blue {
  background:
    linear-gradient(var(--rule-2) 1px, transparent 1px) 0 0 / 24px 24px,
    linear-gradient(90deg, var(--rule-2) 1px, transparent 1px) 0 0 / 24px 24px,
    linear-gradient(0deg, var(--ink2) 0%, color-mix(in srgb, var(--ink2) 50%, var(--bg)) 45%, var(--bg) 100%);
}
.grain::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  opacity: var(--grain-op); mix-blend-mode: var(--grain-blend);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.9 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 240px 240px;
}
:root[data-theme="dark"] .grain::after {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.9 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}
.fig .lock { width: min(46%, 260px); height: auto; color: #171310; position: relative; z-index: 1; }
/* After dark the figure is the dark app icon: the orange lock on charcoal, with the
   orange rising from the foot of the cell. Never a light lock on the orange. */
:root[data-theme="dark"] .fig {
  background:
    linear-gradient(var(--rule-2) 1px, transparent 1px) 0 0 / 24px 24px,
    linear-gradient(90deg, var(--rule-2) 1px, transparent 1px) 0 0 / 24px 24px,
    linear-gradient(0deg, color-mix(in srgb, var(--stamp) 42%, var(--bg)) 0%, var(--bg) 75%);
}
:root[data-theme="dark"] .fig .lock { color: var(--stamp); }
:root[data-theme="dark"] .fig .corner.on-ink, :root[data-theme="dark"] .fig .corner.on-ink .n { color: var(--fg); }
.fig { margin: 0; }
.fig .corner { position: absolute; z-index: 2; max-width: 46%; }
.fig .corner.tl { top: .9rem; left: 1rem; }
.fig .corner.tr { top: .9rem; right: 1rem; text-align: right; }
.fig .corner.bl { bottom: .9rem; left: 1rem; }
.fig .corner.br { bottom: .9rem; right: 1rem; text-align: right; }
.fig .corner.on-ink { color: #171310; }
.fig .corner.on-ink .n { color: #171310; }
.fig .on-blue, .fig .on-blue .n { color: var(--ink2-ink); }
.fig .mark { position: relative; z-index: 1; color: var(--ink2-ink); width: 96px; height: 96px; }

/* ---------- The idea ---------- */
.statement { font-size: clamp(1.7rem, 3.6vw, 3.3rem); max-width: 20ch; margin: 0; }
.abc { display: flex; flex-direction: column; gap: 1rem; }
.abc h3 { font-family: inherit; font-size: 1.05rem; font-weight: 600; letter-spacing: 0; line-height: 1.3; max-width: 22ch; }

/* ---------- Index lists (the products, the refusals, the posts) ---------- */
.idx { list-style: none; margin: 0; padding: 0; }
.idx > li {
  display: grid; grid-template-columns: 3.2rem 1fr auto; column-gap: 1.2rem; align-items: baseline;
  padding: 1rem 0; border-top: 1px solid var(--rule); position: relative;
}
.idx > li:first-child { border-top: 0; padding-top: 0; }
.idx .num { color: var(--fg); }
.idx .what { display: flex; flex-direction: column; gap: .3rem; min-width: 0; }
.idx .what h3 { font-family: inherit; font-size: 1.1rem; font-weight: 600; letter-spacing: 0; line-height: 1.3; }
.idx .what h3 a { color: inherit; text-decoration: none; }
.idx .what h3 a:hover { border-bottom: 1px solid var(--fg); }
.idx .what .sub { color: var(--muted); font-size: .95rem; max-width: 52ch; }
.idx .when { text-align: right; white-space: nowrap; }
.idx .when.now { color: var(--accent); }
.idx .when .dot { display: inline-block; width: 6px; height: 6px; background: currentColor; margin-left: .6rem; vertical-align: middle; }
.idx.plain > li { grid-template-columns: 1fr auto; }
.idx.plain .what .sub { max-width: 60ch; }
.idx.dim > li { color: var(--muted); }
@media (max-width: 560px) {
  .idx > li { grid-template-columns: 2.4rem 1fr; }
  .idx .when { grid-column: 2; text-align: left; margin-top: .2rem; }
  .idx.plain > li { grid-template-columns: 1fr; }
}
.idx .ico { display: inline-grid; place-items: center; width: 22px; height: 22px; color: var(--accent); vertical-align: -6px; margin-right: .5rem; }
.idx .ico svg { width: 22px; height: 22px; }

/* the refusals: a pixel dot at the head, ink; the list reads as a printed checklist */
.refuse > li { grid-template-columns: 1.6rem 1fr; }
.refuse .px { width: 8px; height: 8px; background: var(--fg); position: relative; top: -.05em; }
.refuse .what h3 { font-weight: 500; font-size: 1.05rem; }

/* ---------- The posts: covers first ---------- */
.posts { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); }
.post { border-left: 1px solid var(--rule); display: flex; flex-direction: column; min-width: 0; }
.post:first-child { border-left: 0; }
.post > a { color: inherit; text-decoration: none; display: flex; flex-direction: column; height: 100%; }
.post .cover { min-height: 0; aspect-ratio: 4 / 3; height: auto; }
.post .cover .lock { width: 34%; }
.post .cover .mark { width: 30%; height: auto; }
.post .cover .pxart { width: 62%; height: auto; position: relative; z-index: 1; }
.cover-paper, :root[data-theme="dark"] .cover-paper {
  background:
    linear-gradient(var(--rule-2) 1px, transparent 1px) 0 0 / 24px 24px,
    linear-gradient(90deg, var(--rule-2) 1px, transparent 1px) 0 0 / 24px 24px,
    var(--bg-2);
}
.cover-paper .pxart { color: var(--fg); }
.post .meta { padding: 1.1rem clamp(1.1rem, 2vw, 1.6rem) 1.4rem; border-top: 1px solid var(--rule); display: flex; flex-direction: column; gap: .5rem; flex: 1; }
.post .meta h3 { font-family: inherit; font-size: 1.15rem; font-weight: 600; letter-spacing: 0; line-height: 1.25; text-wrap: balance; }
.post .meta .sub { color: var(--muted); font-size: .95rem; }
.post > a:hover .meta h3 { text-decoration: underline; text-underline-offset: 3px; text-decoration-color: var(--rule); }
@media (max-width: 900px) {
  .posts { grid-template-columns: 1fr; }
  .post { border-left: 0; border-top: 1px solid var(--rule); }
  .post:first-child { border-top: 0; }
}

/* ---------- The question ---------- */
.question { font-size: clamp(2.2rem, 5vw, 4.4rem); max-width: 12ch; margin: 0; }
.question .circled { padding: 0 .16em; }
.asks { list-style: none; margin: 1.4rem 0 0; padding: 0; display: grid; gap: .6rem; }
.asks li { display: flex; gap: .7rem; align-items: baseline; color: var(--fg); }
.asks .pxarrow { width: 14px; height: 14px; flex: none; color: var(--ink2); position: relative; top: .1em; }
.mail { display: inline-flex; align-items: center; gap: .6rem; margin-top: 1.6rem; color: var(--fg); text-decoration: none; }
.mail svg { width: 22px; height: 22px; color: var(--accent); }
.mail span { border-bottom: 1px solid var(--rule); }
.mail:hover span { border-color: var(--fg); }

/* ---------- Newsletter (the form styles come from styles.css) ---------- */
.news-title { font-size: clamp(1.7rem, 3.2vw, 2.6rem); margin: 0 0 .8rem; }
.brand .newsletter-form { max-width: none; margin-top: 1.2rem; text-align: left; }
.brand .form-fine { text-align: left; }
.brand #email { border-radius: 10px; }
.brand .newsletter-form .btn-primary { border-radius: 10px; }

/* ---------- Footer ---------- */
.foot { border-top: 0; }
.foot-links { display: flex; flex-wrap: wrap; gap: .6rem 1.6rem; }
.foot-links a { text-decoration: none; }
.foot-links a:hover { color: var(--fg); }
.dither { display: block; width: 100%; height: auto; aspect-ratio: 192 / 3; image-rendering: pixelated; image-rendering: crisp-edges; }
.socials { display: flex; gap: .9rem; }
.socials a { display: inline-grid; place-items: center; width: 28px; height: 28px; color: var(--muted); }
.socials a:hover { color: var(--fg); }
.socials svg { width: 22px; height: 22px; }


/* ---------- Pixel glyphs ---------- */
.pxgrid { shape-rendering: crispEdges; }

/* ---------- Legal-ish text pages (support, blog) ---------- */
.prose { max-width: 60ch; }
.prose h2 { font-family: inherit; font-size: 1.1rem; font-weight: 600; letter-spacing: 0; margin: 1.8rem 0 .5rem; }
.prose h2:first-child { margin-top: 0; }
.prose p, .prose li { color: var(--muted); line-height: 1.55; }
.prose p + p { margin-top: .8em; }
.prose a { color: var(--fg); }
.prose ul { padding-left: 1.2rem; margin: .5rem 0; }
.prose li { margin-bottom: .4rem; }
.prose code { font-family: "Geist Pixel", ui-monospace, monospace; font-size: .85em; }

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

/* ---------- The tiles: the products as a dashboard ----------
   From the widget reference: a label, one big value, a graphic on the right. Radius 14,
   the recessed paper, ink text. The one that is out is a link and carries the stamp. */
.tiles { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(.8rem, 1.5vw, 1.2rem); }
.tile {
  display: grid; grid-template-columns: 1fr auto; gap: 1.2rem; align-items: center;
  padding: clamp(1.1rem, 2vw, 1.6rem) clamp(1.2rem, 2.2vw, 1.8rem);
  min-height: 176px; border-radius: 14px;
  background: var(--bg-2); color: var(--fg); text-decoration: none;
  border: 1px solid transparent;
}
a.tile { transition: border-color .2s ease, transform .2s ease; }
a.tile:hover { border-color: var(--rule); transform: translateY(-2px); }
.tile-text { display: flex; flex-direction: column; gap: .35rem; min-width: 0; }
.tile-label { font-size: .95rem; font-weight: 500; color: var(--fg); }
.tile-label .lab { color: var(--muted); }
.tile-value { font-size: clamp(1.9rem, 3.4vw, 3rem); line-height: 1; margin: .1rem 0 .25rem; }
a.tile .tile-value { color: var(--accent); }
.tile-sub { color: var(--muted); font-size: .92rem; line-height: 1.45; max-width: 34ch; }
.tile-art-wrap { display: grid; place-items: center; width: clamp(88px, 10vw, 128px); height: clamp(88px, 10vw, 128px); color: var(--fg); }
.tile-art { width: 72%; height: auto; }
.tile-art.lock { width: 58%; }
a.tile .tile-art { color: var(--fg); }
@media (max-width: 900px) { .tiles { grid-template-columns: 1fr; } .tile { min-height: 0; } }

/* ---------- Contact ---------- */
.socials-list { list-style: none; margin: 2rem 0 0; padding: 0; max-width: 28rem; }
.socials-list li { display: grid; grid-template-columns: 6rem 1fr; gap: 1rem; align-items: baseline; padding: .7rem 0; border-top: 1px solid var(--rule); }
.socials-list li:last-child { border-bottom: 1px solid var(--rule); }
.socials-list a { color: var(--fg); text-decoration: none; }
.socials-list a:hover { text-decoration: underline; text-underline-offset: 3px; }
.contact-form { display: flex; flex-direction: column; gap: 1rem; }
.c-field { display: flex; flex-direction: column; gap: .4rem; }
.c-field input, .c-field textarea {
  font: inherit; color: var(--fg); background: var(--card);
  border: 1px solid var(--hairline); border-radius: 10px; padding: .8rem 1rem; width: 100%;
  transition: border-color .2s ease, box-shadow .2s ease;
}
.c-field textarea { resize: vertical; min-height: 7rem; }
.c-field input:focus, .c-field textarea:focus { outline: none; border-color: var(--ink2); box-shadow: 0 0 0 3px color-mix(in srgb, var(--ink2) 22%, transparent); }
.c-field input.invalid { border-color: var(--accent); }
.c-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 1rem 1.4rem; }
.contact-form .btn-primary { background: var(--fg); color: var(--bg); border-radius: 10px; }   /* ink: the stamp is the hero's */

/* ---------- The phone menu: a full-screen numbered list ---------- */
.menu-btn { display: none; background: none; border: 0; padding: .3rem 0; color: var(--fg); }
.menu {
  position: fixed; inset: 0; z-index: 50; background: var(--bg); color: var(--fg);
  display: flex; flex-direction: column; padding: .75rem clamp(1rem, 3vw, 2rem) 2rem;
}
.menu-top { display: flex; align-items: center; justify-content: space-between; height: 34px; }
.menu-close { background: var(--fg); color: var(--bg); border: 0; border-radius: 8px; padding: .45rem .8rem; font: inherit; font-size: .9rem; }
.menu ol { list-style: none; margin: auto 0 0; padding: 0; border-top: 1px solid var(--rule); }
.menu li { border-bottom: 1px solid var(--rule); }
.menu li a {
  display: grid; grid-template-columns: 2.4rem 1fr; align-items: baseline; gap: .6rem;
  padding: .9rem 0; text-decoration: none; color: var(--fg);
  font-family: "Clash Display", ui-sans-serif, system-ui, sans-serif; font-weight: 500; font-size: 1.9rem; letter-spacing: -0.01em;
}
.menu li a .lab { position: relative; top: -.6em; }
.menu li.is-here a { color: var(--accent); }
.menu-eyebrow { margin-bottom: .6rem; }
.menu-open { overflow: hidden; }
@media (max-width: 760px) {
  .mast-nav a.lab { display: none; }
  .menu-btn { display: inline-block; }
}

.menu[hidden] { display: none; }
.socials-list li[hidden] { display: none; }

/* ---------- Fig. 01: the eye, blinking ----------
   Three pixel frames in one SVG (open, half, closed). CSS steps between them: a blink
   every few seconds, and the pupil glances to one side now and then. Nothing tweens;
   every change is a whole pixel, the way a sprite would move. */
.fig .hero-art { width: min(72%, 420px); height: auto; color: #171310; position: relative; z-index: 1; }
:root[data-theme="dark"] .fig .hero-art { color: var(--stamp); }
.eye .f-half, .eye .f-closed { opacity: 0; }
.eye .f-open   { animation: eyeOpen   6.4s steps(1, end) infinite; }
.eye .f-half   { animation: eyeHalf   6.4s steps(1, end) infinite; }
.eye .f-closed { animation: eyeClosed 6.4s steps(1, end) infinite; }
.eye .f-open .pupil { animation: glance 6.4s steps(1, end) infinite; }
@keyframes eyeOpen   { 0%, 41.9% { opacity: 1 } 42%, 46.9% { opacity: 0 } 47%, 89.9% { opacity: 1 } 90%, 94.9% { opacity: 0 } 95%, 100% { opacity: 1 } }
@keyframes eyeHalf   { 0%, 41.9% { opacity: 0 } 42%, 43.4% { opacity: 1 } 43.5%, 45.4% { opacity: 0 } 45.5%, 46.9% { opacity: 1 } 47%, 89.9% { opacity: 0 } 90%, 91.4% { opacity: 1 } 91.5%, 93.4% { opacity: 0 } 93.5%, 94.9% { opacity: 1 } 95%, 100% { opacity: 0 } }
@keyframes eyeClosed { 0%, 43.4% { opacity: 0 } 43.5%, 45.4% { opacity: 1 } 45.5%, 91.4% { opacity: 0 } 91.5%, 93.4% { opacity: 1 } 93.5%, 100% { opacity: 0 } }
@keyframes glance    { 0%, 19.9% { transform: translate(0, 0) } 20%, 34.9% { transform: translate(3px, 0) } 35%, 59.9% { transform: translate(0, 0) } 60%, 72.9% { transform: translate(-3px, 0) } 73%, 100% { transform: translate(0, 0) } }
@media (prefers-reduced-motion: reduce) {
  .eye .f-open, .eye .f-half, .eye .f-closed, .eye .f-open .pupil { animation: none; }
}

/* The blog band is the bright blue as a field, paper text on it, in both themes (Mayara, 09-09). */
.band-blue, :root[data-theme="dark"] .band-blue { background: #0f1eaf; color: #f2f0ea; }
.band-blue .num, .band-blue .note, .band-blue .note a { color: #f2f0ea; opacity: .78; }

/* The last band can only stack if there is enough page left below it to scroll through.
   The newsletter row is padded to that height on wide screens; on phones the bands
   replace each other, so it needs nothing. */
@media (min-width: 901px) {
  .row.last { min-height: calc(100vh - var(--mast) - 5 * var(--band) - 200px); }
}

/* After dark the blue figures keep the bright blue (the earlier dark .fig rule turned them orange). */
:root[data-theme="dark"] .fig-blue {
  background:
    linear-gradient(var(--rule-2) 1px, transparent 1px) 0 0 / 24px 24px,
    linear-gradient(90deg, var(--rule-2) 1px, transparent 1px) 0 0 / 24px 24px,
    linear-gradient(0deg, #0f1eaf 0%, color-mix(in srgb, #0f1eaf 55%, var(--bg)) 45%, var(--bg) 100%);
}
:root[data-theme="dark"] .fig-blue .mark, :root[data-theme="dark"] .fig-blue .on-blue, :root[data-theme="dark"] .fig-blue .on-blue .n { color: #f2f0ea; }

/* ---------- Blog search ----------
   A plain GET form with the field named "s", which is what WordPress's search expects,
   so the same markup works when this becomes a theme. Until then brand.js filters the
   posts on the page as you type. */
.search { display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 1rem; }
.search input {
  font: inherit; color: var(--fg); background: transparent; border: 0; border-bottom: 1px solid var(--rule);
  padding: .5rem 0; width: 100%; min-width: 0; font-size: 1.05rem;
}
.search input:focus { outline: none; border-color: var(--fg); }
.search input::placeholder { color: color-mix(in srgb, var(--muted) 70%, transparent); }
.search button { background: none; border: 0; padding: .4rem 0; color: var(--muted); cursor: pointer; }
.search button:hover { color: var(--fg); }
.search-empty { padding: 2rem clamp(1.1rem, 2.6vw, 2.6rem); color: var(--muted); }
@media (max-width: 560px) { .search { grid-template-columns: 1fr auto; } .search > label { display: none; } }
.post[hidden] { display: none; }

/* ---------- Fig. 01: the lamp ----------
   The body is ink (paper after dark). The light is the orange laid on in translucent
   pixels, with a checkerboard fringe so it fades the way pixel art fades. It starts off,
   clicks on with one flicker, and stays on; every so often it goes off and comes back. */
.fig .lamp { width: min(74%, 440px); }
:root[data-theme="dark"] .fig .lamp { color: var(--fg); }
.lamp .glow { color: var(--stamp); }
.lamp .beam { fill-opacity: .48; }
.lamp .fringe { fill-opacity: .48; }
.lamp .bulb { fill-opacity: 1; }
:root[data-theme="dark"] .lamp .beam, :root[data-theme="dark"] .lamp .fringe { fill-opacity: .5; }
.lamp .glow { animation: lampOn 14s steps(1, end) infinite; }
@keyframes lampOn { 0%, 11.9% { opacity: 0 } 12%, 12.9% { opacity: 1 } 13%, 14.4% { opacity: 0 } 14.5%, 100% { opacity: 1 } }
@media (prefers-reduced-motion: reduce) { .lamp .glow { animation: none; opacity: 1; } }
.tile-art.eye { width: 92%; }


/* ---------- Fig. 01: the desk ----------
   Books, a lamp, a mug. Three things move, all in whole pixels: the steam swaps between
   two shapes; the cord pulls down and the light comes on (and later pulls again and it goes
   off); while it is on, a dithered halo spreads over the desk and the figure's own ground
   warms with it. 14 s cycle. */
.fig .scene { width: min(90%, 560px); }
:root[data-theme="dark"] .fig .scene { color: var(--fg); }
.scene .glow { color: var(--stamp); opacity: 0; animation: lightOn 14s steps(1, end) infinite; }
.scene .h1 { fill-opacity: .5; } .scene .h2 { fill-opacity: .5; } .scene .h3 { fill-opacity: .5; }
:root[data-theme="dark"] .scene .h1, :root[data-theme="dark"] .scene .h2, :root[data-theme="dark"] .scene .h3 { fill-opacity: .6; }
.scene .cord { animation: cordPull 14s steps(1, end) infinite; }
.scene .steam-b { opacity: 0; }
.scene .steam-a { animation: steamA 1.6s steps(1, end) infinite; }
.scene .steam-b { animation: steamB 1.6s steps(1, end) infinite; }
/* the ground behind the figure warms with the light */
.fig.lit::before {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none; opacity: 0;
  background: radial-gradient(ellipse 48% 42% at 50% 46%, color-mix(in srgb, var(--stamp) 60%, transparent), transparent 72%);
  animation: lightOn 14s steps(1, end) infinite;
}
@keyframes lightOn  { 0%, 11.4% { opacity: 0 } 11.5%, 12.4% { opacity: 1 } 12.5%, 13.1% { opacity: 0 } 13.2%, 81.4% { opacity: 1 } 81.5%, 100% { opacity: 0 } }
@keyframes cordPull { 0%, 9.9% { transform: translate(0, 0) } 10%, 11.4% { transform: translate(0, 3px) } 11.5%, 79.9% { transform: translate(0, 0) } 80%, 81.4% { transform: translate(0, 3px) } 81.5%, 100% { transform: translate(0, 0) } }
@keyframes steamA { 0%, 49.9% { opacity: 1 } 50%, 100% { opacity: 0 } }
@keyframes steamB { 0%, 49.9% { opacity: 0 } 50%, 100% { opacity: 1 } }
@media (prefers-reduced-motion: reduce) {
  .scene .glow, .fig.lit::before { animation: none; opacity: 1; }
  .scene .cord, .scene .steam-a, .scene .steam-b { animation: none; }
  .scene .steam-b { opacity: 0; }
}

/* ---------- The lock: it opens and closes ----------
   Two shackles in one drawing; the open one has risen and unhooked on the left. Closed
   most of the time, open for a few seconds, then shut again. */
.tile-art.lock { width: 52%; }
.lock .sh-open { opacity: 0; }
.lock .sh-closed { animation: lockClosed 9s steps(1, end) infinite; }
.lock .sh-open { animation: lockOpen 9s steps(1, end) infinite; }
@keyframes lockClosed { 0%, 59.9% { opacity: 1 } 60%, 89.9% { opacity: 0 } 90%, 100% { opacity: 1 } }
@keyframes lockOpen   { 0%, 59.9% { opacity: 0 } 60%, 89.9% { opacity: 1 } 90%, 100% { opacity: 0 } }
@media (prefers-reduced-motion: reduce) { .lock .sh-closed, .lock .sh-open { animation: none; } .lock .sh-open { opacity: 0; } }

/* ---------- The pencil: it scribbles ----------
   Ported from Mayara's frame script (09-09): her 22x22 pencil sprite, its tip on a looping
   path across a 64x40 sheet, 34 drawing frames at 70 ms and a short hold while it lifts
   away. The pencil is a sprite with an opaque body so it passes in front of its own line;
   the line is revealed one frame's worth of pixels at a time. Whole pixels only. */
.tile-art.pencil { width: 100%; }
.tile-art-wrap:has(.pencil) { width: clamp(170px, 18vw, 224px); }
.pencil .pbody { fill: var(--bg-2); }
.pencil .pen { animation: penPath 2870ms steps(1, end) infinite; }
.pencil .trail g { opacity: 0; }
@keyframes penPath { 0.0%, 2.43% { transform: translate(7px, 10px); opacity: 1 } 2.44%, 4.87% { transform: translate(5px, 7px); opacity: 1 } 4.88%, 7.31% { transform: translate(4px, 6px); opacity: 1 } 7.32%, 9.75% { transform: translate(7px, 4px); opacity: 1 } 9.76%, 12.19% { transform: translate(11px, 2px); opacity: 1 } 12.2%, 14.62% { transform: translate(15px, 2px); opacity: 1 } 14.63%, 17.06% { transform: translate(18px, 5px); opacity: 1 } 17.07%, 19.50% { transform: translate(18px, 9px); opacity: 1 } 19.51%, 21.94% { transform: translate(16px, 10px); opacity: 1 } 21.95%, 24.38% { transform: translate(14px, 9px); opacity: 1 } 24.39%, 26.82% { transform: translate(13px, 9px); opacity: 1 } 26.83%, 29.26% { transform: translate(14px, 8px); opacity: 1 } 29.27%, 31.70% { transform: translate(18px, 6px); opacity: 1 } 31.71%, 34.14% { transform: translate(23px, 5px); opacity: 1 } 34.15%, 36.58% { transform: translate(26px, 8px); opacity: 1 } 36.59%, 39.01% { transform: translate(27px, 10px); opacity: 1 } 39.02%, 41.45% { transform: translate(25px, 10px); opacity: 1 } 41.46%, 43.89% { transform: translate(23px, 8px); opacity: 1 } 43.9%, 46.33% { transform: translate(21px, 7px); opacity: 1 } 46.34%, 48.77% { transform: translate(22px, 5px); opacity: 1 } 48.78%, 51.21% { transform: translate(25px, 2px); opacity: 1 } 51.22%, 53.65% { transform: translate(30px, 1px); opacity: 1 } 53.66%, 56.09% { transform: translate(34px, 4px); opacity: 1 } 56.1%, 58.53% { transform: translate(35px, 7px); opacity: 1 } 58.54%, 60.97% { transform: translate(34px, 9px); opacity: 1 } 60.98%, 63.40% { transform: translate(32px, 9px); opacity: 1 } 63.41%, 65.84% { transform: translate(30px, 10px); opacity: 1 } 65.85%, 68.28% { transform: translate(30px, 9px); opacity: 1 } 68.29%, 70.72% { transform: translate(33px, 7px); opacity: 1 } 70.73%, 73.16% { transform: translate(37px, 5px); opacity: 1 } 73.17%, 75.60% { transform: translate(41px, 7px); opacity: 1 } 75.61%, 78.04% { transform: translate(44px, 10px); opacity: 1 } 78.05%, 80.48% { transform: translate(43px, 10px); opacity: 1 } 80.49%, 82.92% { transform: translate(41px, 9px); opacity: 1 } 82.93%, 85.36% { transform: translate(41px, 10px); opacity: 1 } 85.37%, 87.79% { transform: translate(41px, 10px); opacity: 1 } 87.8%, 90.23% { transform: translate(41px, 10px); opacity: 1 } 90.24%, 92.67% { transform: translate(41px, 10px); opacity: 1 } 92.68%, 95.11% { transform: translate(41px, 10px); opacity: 0 } 95.12%, 97.55% { transform: translate(41px, 10px); opacity: 0 } 97.56%, 99.99% { transform: translate(41px, 10px); opacity: 0 } }
.pencil .s0 { animation: ps0 2870ms steps(1, end) infinite; } @keyframes ps0 { 0%, -0.01% { opacity: 0 } 0.0%, 100% { opacity: 1 } }
.pencil .s1 { animation: ps1 2870ms steps(1, end) infinite; } @keyframes ps1 { 0%, 2.43% { opacity: 0 } 2.44%, 100% { opacity: 1 } }
.pencil .s2 { animation: ps2 2870ms steps(1, end) infinite; } @keyframes ps2 { 0%, 4.87% { opacity: 0 } 4.88%, 100% { opacity: 1 } }
.pencil .s3 { animation: ps3 2870ms steps(1, end) infinite; } @keyframes ps3 { 0%, 7.31% { opacity: 0 } 7.32%, 100% { opacity: 1 } }
.pencil .s4 { animation: ps4 2870ms steps(1, end) infinite; } @keyframes ps4 { 0%, 9.75% { opacity: 0 } 9.76%, 100% { opacity: 1 } }
.pencil .s5 { animation: ps5 2870ms steps(1, end) infinite; } @keyframes ps5 { 0%, 12.19% { opacity: 0 } 12.2%, 100% { opacity: 1 } }
.pencil .s6 { animation: ps6 2870ms steps(1, end) infinite; } @keyframes ps6 { 0%, 14.62% { opacity: 0 } 14.63%, 100% { opacity: 1 } }
.pencil .s7 { animation: ps7 2870ms steps(1, end) infinite; } @keyframes ps7 { 0%, 17.06% { opacity: 0 } 17.07%, 100% { opacity: 1 } }
.pencil .s8 { animation: ps8 2870ms steps(1, end) infinite; } @keyframes ps8 { 0%, 19.50% { opacity: 0 } 19.51%, 100% { opacity: 1 } }
.pencil .s9 { animation: ps9 2870ms steps(1, end) infinite; } @keyframes ps9 { 0%, 21.94% { opacity: 0 } 21.95%, 100% { opacity: 1 } }
.pencil .s10 { animation: ps10 2870ms steps(1, end) infinite; } @keyframes ps10 { 0%, 24.38% { opacity: 0 } 24.39%, 100% { opacity: 1 } }
.pencil .s11 { animation: ps11 2870ms steps(1, end) infinite; } @keyframes ps11 { 0%, 26.82% { opacity: 0 } 26.83%, 100% { opacity: 1 } }
.pencil .s12 { animation: ps12 2870ms steps(1, end) infinite; } @keyframes ps12 { 0%, 29.26% { opacity: 0 } 29.27%, 100% { opacity: 1 } }
.pencil .s13 { animation: ps13 2870ms steps(1, end) infinite; } @keyframes ps13 { 0%, 31.70% { opacity: 0 } 31.71%, 100% { opacity: 1 } }
.pencil .s14 { animation: ps14 2870ms steps(1, end) infinite; } @keyframes ps14 { 0%, 34.14% { opacity: 0 } 34.15%, 100% { opacity: 1 } }
.pencil .s15 { animation: ps15 2870ms steps(1, end) infinite; } @keyframes ps15 { 0%, 36.58% { opacity: 0 } 36.59%, 100% { opacity: 1 } }
.pencil .s16 { animation: ps16 2870ms steps(1, end) infinite; } @keyframes ps16 { 0%, 39.01% { opacity: 0 } 39.02%, 100% { opacity: 1 } }
.pencil .s17 { animation: ps17 2870ms steps(1, end) infinite; } @keyframes ps17 { 0%, 41.45% { opacity: 0 } 41.46%, 100% { opacity: 1 } }
.pencil .s18 { animation: ps18 2870ms steps(1, end) infinite; } @keyframes ps18 { 0%, 43.89% { opacity: 0 } 43.9%, 100% { opacity: 1 } }
.pencil .s19 { animation: ps19 2870ms steps(1, end) infinite; } @keyframes ps19 { 0%, 46.33% { opacity: 0 } 46.34%, 100% { opacity: 1 } }
.pencil .s20 { animation: ps20 2870ms steps(1, end) infinite; } @keyframes ps20 { 0%, 48.77% { opacity: 0 } 48.78%, 100% { opacity: 1 } }
.pencil .s21 { animation: ps21 2870ms steps(1, end) infinite; } @keyframes ps21 { 0%, 51.21% { opacity: 0 } 51.22%, 100% { opacity: 1 } }
.pencil .s22 { animation: ps22 2870ms steps(1, end) infinite; } @keyframes ps22 { 0%, 53.65% { opacity: 0 } 53.66%, 100% { opacity: 1 } }
.pencil .s23 { animation: ps23 2870ms steps(1, end) infinite; } @keyframes ps23 { 0%, 56.09% { opacity: 0 } 56.1%, 100% { opacity: 1 } }
.pencil .s24 { animation: ps24 2870ms steps(1, end) infinite; } @keyframes ps24 { 0%, 58.53% { opacity: 0 } 58.54%, 100% { opacity: 1 } }
.pencil .s25 { animation: ps25 2870ms steps(1, end) infinite; } @keyframes ps25 { 0%, 60.97% { opacity: 0 } 60.98%, 100% { opacity: 1 } }
.pencil .s26 { animation: ps26 2870ms steps(1, end) infinite; } @keyframes ps26 { 0%, 63.40% { opacity: 0 } 63.41%, 100% { opacity: 1 } }
.pencil .s27 { animation: ps27 2870ms steps(1, end) infinite; } @keyframes ps27 { 0%, 65.84% { opacity: 0 } 65.85%, 100% { opacity: 1 } }
.pencil .s28 { animation: ps28 2870ms steps(1, end) infinite; } @keyframes ps28 { 0%, 68.28% { opacity: 0 } 68.29%, 100% { opacity: 1 } }
.pencil .s29 { animation: ps29 2870ms steps(1, end) infinite; } @keyframes ps29 { 0%, 70.72% { opacity: 0 } 70.73%, 100% { opacity: 1 } }
.pencil .s30 { animation: ps30 2870ms steps(1, end) infinite; } @keyframes ps30 { 0%, 73.16% { opacity: 0 } 73.17%, 100% { opacity: 1 } }
.pencil .s31 { animation: ps31 2870ms steps(1, end) infinite; } @keyframes ps31 { 0%, 75.60% { opacity: 0 } 75.61%, 100% { opacity: 1 } }
.pencil .s32 { animation: ps32 2870ms steps(1, end) infinite; } @keyframes ps32 { 0%, 78.04% { opacity: 0 } 78.05%, 100% { opacity: 1 } }
.pencil .s33 { animation: ps33 2870ms steps(1, end) infinite; } @keyframes ps33 { 0%, 80.48% { opacity: 0 } 80.49%, 100% { opacity: 1 } }
@media (prefers-reduced-motion: reduce) { .pencil .pen, .pencil .trail g { animation: none; } .pencil .trail g { opacity: 1; } .pencil .pen { transform: translate(41px, 10px); } }
.tile-art-wrap { position: relative; }

/* ---------- The Polaroid: a picture develops ----------
   Ported from Mayara's frame script (09-09): a tilted instant photo, 1-px outlines. The
   window is blank, a chemical wash blooms, mountains and a sun resolve out of it as it
   clears, hold, then a quick dissolve so the loop is seamless. The 44 frames of the window
   live in one sprite strip (a tiny PNG inside the SVG) that steps past a clip, 80 ms a
   frame. The card's white is the tile's own paper so it hides nothing it should not. */
.polaroid .card { fill: var(--bg-2); }
.polaroid .film { image-rendering: pixelated; image-rendering: crisp-edges; animation: develop 3520ms steps(44, end) infinite; }
:root[data-theme="dark"] .polaroid .film { filter: invert(1) brightness(.95); }
@keyframes develop { to { transform: translate(0, -2728px); } }
@media (prefers-reduced-motion: reduce) { .polaroid .film { animation: none; transform: translate(0, -1860px); } }

/* ---------- A blog post ----------
   A cover across the sheet, then the meta column on the left and the article on the right.
   Running text near 65 characters, one pull quote in the display face, one draft note. */
.post-cover { aspect-ratio: 21 / 8; min-height: 0; height: auto; }
.post-cover .lock { width: auto; height: 62%; }
.post-title { font-size: clamp(2rem, 4.4vw, 4rem); max-width: 16ch; margin: 0 0 1.6rem; text-wrap: balance; }
.meta-list { list-style: none; margin: 0; padding: 0; }
.meta-list li { display: flex; flex-direction: column; gap: .2rem; padding: .7rem 0; border-top: 1px solid var(--rule); }
.meta-list li:last-child { border-bottom: 1px solid var(--rule); }
.meta-list li span:last-child { font-size: .95rem; }
.post-meta .draft { margin-top: 1.6rem; color: var(--accent); max-width: 24ch; }
.article { max-width: 64ch; }
.article p { font-size: 1.12rem; line-height: 1.65; color: var(--fg); margin: 0 0 1.25em; }
.article p.lede { font-size: 1.3rem; line-height: 1.5; color: var(--muted); }
.article h2 { font-family: "Clash Display", ui-sans-serif, system-ui, sans-serif; font-weight: 600; font-size: 1.6rem; letter-spacing: -0.01em; line-height: 1.1; margin: 2.2rem 0 .8rem; }
.article .pull { font-size: clamp(1.4rem, 2.6vw, 2.1rem); line-height: 1.15; margin: 2rem 0; padding: 1.2rem 0 1.2rem 1.4rem; border-left: 4px solid var(--stamp); color: var(--fg); }
.article a { color: var(--fg); }
.next .next-title { font-size: 1.4rem; margin-top: .4rem; }
@media (max-width: 900px) { .post-cover { aspect-ratio: 16 / 9; } .post-meta { order: 2; } }
