/* ==========================================================================
   Tiltrow — website styles
   The app's own Slate skin, straight out of lib/app/theme.dart's
   Palette.slate: the page is the app's page colour, the cards are its
   cards, and the gold is its brass. Tiltrow ships eight materials; the
   site wears the dark one, because a page is read at night too.
   No web fonts, no CDN, no trackers: the page is one request plus images.

   Copied from glide-merge/assets/site.css. A project folder on this site
   is self-contained (CLAUDE.md §2) — nothing here is shared with that one,
   and a change there is not a change here.
   ========================================================================== */

:root {
  /* Palette.ash — the skin the app opens on, so the page and the first
     screenshot are the same material. Every value below is measured
     against the page and against a card; the numbers are the contrast
     ratios, and nothing here is picked by eye.

     The page is the tray's face lifted a step (#E9DFCB -> #EFE7D8), not
     the app's mat (#B5B2A8). On the mat the app's brass reads 1.6 against
     the text around it — fine behind a wooden tray, unreadable as a link
     on a web page. */
  --ink:        #efe7d8;   /* the page: pale ash */
  --ink-2:      #e4dac6;   /* the demo tray: a well below the page */
  --surface:    #e6ddcb;   /* Palette.ash.carve */
  --surface-2:  #efe7d800; /* unused slot kept for clarity */
  --card:       #faf6ee;   /* Palette.ash.card */
  --card-hi:    #ffffff;
  --board:      #e9dfcb;   /* Palette.ash.face */
  --cell:       #dcd0b8;   /* Palette.ash.well */

  --gold:       #7a5e22;   /* links and accents: 4.95 on page, 5.64 on card */
  --gold-deep:  #5e4818;
  --brass:      #a98437;   /* Palette.ash.brass — marks and rules, never text */
  --moss:       #6f8450;   /* Palette.ash.moss */
  --cream:      #32291e;   /* Palette.ash.ink — the text colour: 11.6 on page */
  --muted:      #4a4338;
  --muted-dim:  #564e41;   /* Palette.ash.dim — 6.7 on page, 7.6 on a card */

  --line:       rgba(50, 41, 30, .16);
  --line-soft:  rgba(50, 41, 30, .07);

  /* Warm and light. The dark theme's blacks at .35 to .55 turn a pale
     wooden page grey. */
  --shadow-sm:  0 2px 8px rgba(58, 44, 28, .14);
  --shadow-md:  0 12px 30px rgba(58, 44, 28, .18);
  --shadow-lg:  0 26px 60px rgba(58, 44, 28, .22);

  --r-sm: 10px;
  --r:    16px;
  --r-lg: 22px;
  --r-xl: 28px;

  --pad: clamp(20px, 5vw, 40px);
  --maxw: 1140px;

  --sans: "Manrope", "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
          "Helvetica Neue", Arial, sans-serif;
}

* { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  scroll-padding-top: 88px;
  -webkit-text-size-adjust: 100%;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    transition-duration: .001ms !important;
  }
}

body {
  margin: 0;
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.65;
  color: var(--cream);
  background: var(--ink);
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; height: auto; display: block; }

a { color: var(--gold); text-decoration: none; }
a:hover { text-decoration: underline; }

::selection { background: var(--gold); color: #faf6ee; }

:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 3px;
  border-radius: 6px;
}

.wrap {
  width: 100%;
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 0 var(--pad);
}

.skip {
  position: absolute;
  left: -9999px;
}
.skip:focus {
  left: 16px; top: 16px;
  z-index: 100;
  background: var(--gold);
  color: #2a1b0e;
  padding: 10px 16px;
  border-radius: var(--r-sm);
  font-weight: 700;
}

/* ---------------------------------------------------------------- type --- */

h1, h2, h3 {
  line-height: 1.12;
  letter-spacing: -.02em;
  margin: 0 0 .5em;
  font-weight: 800;
}

h1 { font-size: clamp(2.3rem, 6.2vw, 4rem); }
h2 { font-size: clamp(1.7rem, 3.8vw, 2.5rem); }
h3 { font-size: 1.12rem; letter-spacing: -.01em; }

p { margin: 0 0 1em; }

.lead {
  font-size: clamp(1.05rem, 2.2vw, 1.25rem);
  color: var(--muted);
  max-width: 60ch;
}

/* A plain line of words over a heading: sentence case, in the quiet ink.
   It was small gold capitals with wide tracking, which is decoration. */
.eyebrow {
  display: block;
  font-size: .95rem;
  font-weight: 600;
  color: var(--muted-dim);
  margin-bottom: 10px;
}

.gold { color: var(--gold); }

/* -------------------------------------------------------------- header --- */

/* Solid, with one hairline. It was frosted glass that grew a border on
   scroll; a header only has to stay out of the way. */
.site-head {
  position: sticky;
  top: 0;
  z-index: 40;
  background: var(--ink);
  border-bottom: 1px solid var(--line);
}

.site-head .wrap {
  display: flex;
  align-items: center;
  gap: 18px;
  height: 68px;
}

.crumb {
  color: var(--muted-dim);
  font-size: .85rem;
  font-weight: 600;
  text-decoration: none;
  padding-right: 18px;
  border-right: 1px solid var(--line);
}
.crumb:hover { color: var(--gold); text-decoration: none; }
@media (max-width: 620px) { .crumb span { display: none; } }
/* On a phone the way back is the arrow alone. With "ByteOnyx" spelt out,
   the privacy page's header was 13 px wider than a 390 px screen and the
   whole page slid sideways. The words stay for a screen reader: text at
   size 0 is still read. */
@media (max-width: 440px) {
  .crumb { padding-right: 10px; font-size: 0; }
  .crumb::before { content: "\2190"; font-size: 1.05rem; }
}

.brand {
  display: flex;
  align-items: center;
  gap: 11px;
  color: var(--cream);
  font-weight: 800;
  letter-spacing: -.02em;
  font-size: 1.06rem;
  text-decoration: none;
  flex: 0 0 auto;
}
.brand:hover { text-decoration: none; }
.brand img {
  width: 32px; height: 32px;
  border-radius: 9px;
}

.nav {
  display: flex;
  gap: 26px;
  margin-left: auto;
  font-size: .95rem;
}
.nav a {
  color: var(--muted);
  text-decoration: none;
  padding: 6px 0;
  border-bottom: 2px solid transparent;
  transition: color .2s ease, border-color .2s ease;
}
.nav a:hover { color: var(--cream); border-bottom-color: var(--gold-deep); }

.head-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: 0 0 auto;
}

/* the language pill: same size as the CTA, quieter */
.lang {
  font-weight: 600;
  letter-spacing: 0;
}

@media (max-width: 860px) {
  .nav { display: none; }
  .head-actions { margin-left: auto; }
}
@media (max-width: 440px) {
  .site-head .wrap { gap: 10px; }
  /* the wordmark comes off the bar, but stays in the accessibility tree —
     display:none would leave the link with no name at all */
  .brand span {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px; padding: 0; border: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
  .btn-sm { padding: 9px 13px; }
}

/* The smallest phones: let the bar take a second row before it lets the
   page scroll sideways. */
@media (max-width: 360px) {
  .site-head .wrap {
    height: auto;
    min-height: 68px;
    flex-wrap: wrap;
    row-gap: 6px;
    padding-top: 8px;
    padding-bottom: 8px;
  }
}

/* ------------------------------------------------------------- buttons --- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  padding: 13px 22px;
  border-radius: 8px;
  font-weight: 700;
  font-size: .97rem;
  letter-spacing: -.01em;
  text-decoration: none;
  border: 1px solid transparent;
  cursor: pointer;
  white-space: nowrap;
  transition: background-color .15s ease, border-color .15s ease;
}
.btn:hover { text-decoration: none; }

/* One flat colour. No gradient, no glow under it, and it does not lift. */
.btn-primary { background: var(--cream); color: #faf6ee; }
.btn-primary:hover { background: #4a3d2d; }

.btn-ghost {
  background: none;
  color: var(--cream);
  border-color: rgba(50, 41, 30, .34);
}
.btn-ghost:hover { background: rgba(50, 41, 30, .06); border-color: var(--cream); }

.btn-sm { padding: 9px 17px; font-size: .9rem; }

.btn svg { width: 18px; height: 18px; flex: 0 0 auto; }

/* ---------------------------------------------------------------- hero --- */

.hero {
  padding: clamp(36px, 6vw, 68px) 0 clamp(32px, 5vw, 56px);
}

.hero .wrap {
  display: grid;
  grid-template-columns: 1.05fr .95fr;
  gap: clamp(32px, 5vw, 64px);
  align-items: center;
}

.hero h1 { margin-bottom: 18px; }
.hero h1 .num { font-variant-numeric: tabular-nums; }

.hero-cta {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin: 28px 0 22px;
}

/* A line of plain words. They were pills, and a pill reads as a button. */
.badges {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 22px;
  list-style: none;
  padding: 0;
  margin: 0;
  font-size: .92rem;
  color: var(--muted);
}
.badges li {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.badges li::before {
  content: "";
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--muted-dim);
}

@media (max-width: 900px) {
  .hero .wrap { grid-template-columns: 1fr; }
  .hero-art { order: -1; max-width: 420px; margin: 0 auto; }
}

/* ------------------------------------------------------- playable demo --- */

.demo {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  padding: 18px;
}

.demo-top {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 14px;
}

.demo-title {
  font-size: .74rem;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--muted-dim);
  margin-right: auto;
}

.stat {
  min-width: 76px;
  text-align: center;
  background: var(--surface);
  border: 1px solid var(--line-soft);
  border-radius: var(--r-sm);
  padding: 6px 12px;
  line-height: 1.2;
}
.stat span {
  display: block;
  font-size: .62rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--muted-dim);
}
.stat b {
  font-size: 1.02rem;
  font-variant-numeric: tabular-nums;
  color: var(--cream);
}

.board {
  position: relative;
  aspect-ratio: 1;
  background: var(--board);
  border-radius: var(--r-lg);
  border: 1px solid rgba(58, 44, 28, .18);
  box-shadow: inset 0 2px 10px rgba(58, 44, 28, .14);
  touch-action: none;
  overflow: hidden;
  container-type: inline-size;
}

.board .cell,
.board .tile {
  position: absolute;
  width: 21.25%;
  height: 21.25%;
  border-radius: 12px;
}

.board .cell { background: var(--cell); opacity: .55; }

.board .tile {
  display: grid;
  place-items: center;
  font-weight: 800;
  letter-spacing: -.03em;
  font-variant-numeric: tabular-nums;
  font-size: 7.4cqw;
  box-shadow: 0 2px 0 rgba(58, 44, 28, .18), inset 0 1px 0 rgba(255, 255, 255, .55);
  transition: left .13s ease-in-out, top .13s ease-in-out;
  will-change: left, top;
}

.board .tile.len3 { font-size: 6cqw; }
.board .tile.len4 { font-size: 4.9cqw; }
.board .tile.len5 { font-size: 4.1cqw; }

.tile-new { animation: pop-in .18s ease-out backwards; }
.tile-merged { animation: pop .18s ease-out; }

@keyframes pop-in {
  from { transform: scale(.3); opacity: 0; }
  to   { transform: scale(1);  opacity: 1; }
}
@keyframes pop {
  0%   { transform: scale(1); }
  55%  { transform: scale(1.16); }
  100% { transform: scale(1); }
}

.demo-hint {
  margin: 13px 2px 0;
  font-size: .84rem;
  color: var(--muted-dim);
  display: flex;
  align-items: center;
  gap: 10px;
}
.demo-hint button {
  margin-left: auto;
  background: none;
  border: 1px solid var(--line);
  color: var(--muted);
  border-radius: 6px;
  padding: 5px 13px;
  font: inherit;
  font-size: .82rem;
  cursor: pointer;
}
.demo-hint button:hover { color: var(--cream); border-color: var(--gold-deep); }

.demo-won {
  color: var(--gold);
  font-weight: 700;
}

/* ------------------------------------------------------------ sections --- */

section { padding: clamp(40px, 6vw, 68px) 0; }

.section-head { max-width: 62ch; margin-bottom: clamp(20px, 3vw, 32px); }
.section-head.center { margin-left: auto; margin-right: auto; text-align: center; }

.rule { border: 0; border-top: 1px solid var(--line-soft); margin: 0; }

/* ---------------------------------------------------------------- grid --- */

.grid {
  display: grid;
  gap: 22px 28px;
}
.g-2 { grid-template-columns: repeat(2, 1fr); }
.g-3 { grid-template-columns: repeat(3, 1fr); }
.g-4 { grid-template-columns: repeat(4, 1fr); }

@media (max-width: 900px) {
  .g-3, .g-4 { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 560px) {
  .g-2, .g-3, .g-4 { grid-template-columns: 1fr; }
}

/* A column under a hairline, not a box. Nothing here is a link, so
   nothing should look as if it lifts when the pointer is over it. */
.card {
  border-top: 1px solid var(--line);
  padding: 18px 0 0;
}
.card p { color: var(--muted); margin-bottom: 0; font-size: .96rem; }
.card h3 { margin-bottom: 8px; }

.card-ico { margin-bottom: 12px; }
.card-ico svg { display: block; width: 24px; height: 24px; stroke: var(--gold); }

/* ------------------------------------------------------------- how-to  --- */

.steps { counter-reset: step; }

.step { position: relative; }
/* The step's number, as a number. */
.step .n {
  display: block;
  font-size: 1.7rem;
  font-weight: 800;
  line-height: 1;
  color: var(--gold);
  font-variant-numeric: tabular-nums;
  margin-bottom: 12px;
}

/* -------------------------------------------------------------- themes --- */

.looks { gap: 16px; }

.look {
  border-radius: 12px;
  border: 1px solid var(--line);
  overflow: hidden;
  background: var(--card);
}

/* A swatch, not a screenshot. Square made seven tall cards fill the screen
   and pushed everything under them off it, so the board is a wide strip with
   a hard height cap — enough to read the material and the tile ramp. */
/* A fixed height, not an aspect ratio: seven square boards filled the whole
   screen and pushed the screenshots and the FAQ off it. Height in px, not %,
   because percentage padding resolves against the WIDTH — a % here made the
   tiles tall and thin as the card grew. */
.look-board {
  height: 100px;
  padding: 13px;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
}
.look-board i {
  border-radius: 7px;
  display: grid;
  place-items: center;
  font-style: normal;
  font-weight: 800;
  font-size: .78rem;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .55);
}
@media (max-width: 700px) {
  .look-board { height: 92px; padding: 11px; gap: 7px; }
}

.look-foot {
  padding: 11px 14px 13px;
  border-top: 1px solid var(--line-soft);
}
.look-foot b { display: block; font-size: .98rem; }
.look-foot span { font-size: .82rem; color: var(--muted-dim); }
.look-foot .free { color: var(--gold); }

/* --------------------------------------------------------------- skins --- */
/* One row a skin: what it is and what it costs on the left, its seven
   marbles on the right, each in a well of that skin's own tray. The
   pictures are the app's paint (assets/marbles/, made by the app repo's
   tool/site_marbles.dart) and --face and --well are the skin's own two
   colours, set on the row. */

.skins {
  list-style: none;
  margin: 0;
  padding: 0;
  border-top: 1px solid var(--line);
}
.skin {
  display: grid;
  grid-template-columns: minmax(0, 300px) minmax(0, 1fr);
  gap: 18px clamp(28px, 5vw, 56px);
  align-items: start;
  padding: 26px 0;
  border-bottom: 1px solid var(--line);
}
.skin h3 { font-size: 1.4rem; margin-bottom: 6px; }
.skin p { margin: 0 0 6px; font-size: .97rem; color: var(--muted); }
.skin p:last-child { margin-bottom: 0; }
.skin-how b { color: var(--cream); }

.marbles {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 12px 8px;
}
.marbles li {
  text-align: center;
  font-size: .8rem;
  line-height: 1.25;
  color: var(--muted);
  overflow-wrap: anywhere;
}
/* The tray, cut to one well: the face, then the well sunk in it. */
.m-well {
  position: relative;
  display: block;
  aspect-ratio: 1;
  margin-bottom: 7px;
  border-radius: 10px;
  background: var(--face);
  overflow: hidden;
}
.m-well::before {
  content: "";
  position: absolute;
  inset: 12%;
  border-radius: 50%;
  background: var(--well);
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, .22);
}
/* The picture is wider than the tile on purpose. The marble's body is 45 %
   of its file — the rest is room for Saturn's rings and a lantern's glow —
   so at 140 % the body sits just inside the well, as it does in the app. */
.m-well img {
  position: absolute;
  left: -20%;
  top: -20%;
  width: 140%;
  max-width: none;
}

@media (max-width: 860px) {
  .skin { grid-template-columns: minmax(0, 1fr); }
  .marbles { max-width: 620px; }
}
/* Seven across a phone is 44 px a marble and a name nobody can read.
   Four, then three. */
@media (max-width: 520px) {
  .marbles { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px 10px; }
}

/* --------------------------------------------------------- screenshots --- */

#screens { padding-bottom: clamp(40px, 6vw, 70px); }
#screens .section-head { margin-bottom: clamp(20px, 3vw, 30px); }

.shots {
  display: flex;
  gap: 18px;
  overflow-x: auto;
  padding: 6px var(--pad) 26px;
  margin: 0 calc(var(--pad) * -1);
  scroll-snap-type: x mandatory;
  scrollbar-width: thin;
  scrollbar-color: var(--card-hi) transparent;
}
.shots::-webkit-scrollbar { height: 8px; }
.shots::-webkit-scrollbar-thumb {
  background: var(--card-hi);
  border-radius: 999px;
}

.shots figure {
  margin: 0;
  flex: 0 0 auto;
  width: min(62vw, 236px);
  scroll-snap-align: center;
}
/* The cards are laid straight into .shots, with no <figure> around them,
   so they need the width a figure would have carried. They are the store
   set: 9:16, wider than the 1080x2424 phone shot the rule above was
   written for, so they get more room. Without this they fall back to
   their intrinsic 1080 px and the row runs off the page. */
.shots > img {
  flex: 0 0 auto;
  width: min(74vw, 292px);
  height: auto;
  scroll-snap-align: center;
}
.shots img {
  border-radius: 12px;
  border: 1px solid var(--line);
  background: var(--card);
}
.shots figcaption {
  margin-top: 11px;
  font-size: .85rem;
  color: var(--muted-dim);
  text-align: center;
}

/* ------------------------------------------------------------ features --- */

.feats {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 2px 34px;
}
.feats li {
  display: flex;
  gap: 12px;
  padding: 13px 0;
  border-bottom: 1px solid var(--line);
  font-size: .97rem;
  color: var(--muted);
}
.feats li b { color: var(--cream); font-weight: 700; }
@media (max-width: 700px) { .feats { grid-template-columns: 1fr; } }

/* --------------------------------------------------------- play games  --- */

.split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(28px, 5vw, 56px);
  align-items: center;
}
@media (max-width: 860px) { .split { grid-template-columns: 1fr; } }

/* A panel is flat: one hairline, no gradient, no shadow. When all it
   holds is a screenshot, the box goes and the screenshot stays at a
   phone's width — stretched to half the page it was a poster. */
.panel {
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: clamp(20px, 3vw, 30px);
}
.panel:has(> img:only-child) { border: 0; padding: 0; }
.panel > img:only-child {
  width: min(100%, 320px);
  margin: 0 auto;
  border-radius: 14px;
  border: 1px solid var(--line);
}

.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 9px;
  list-style: none;
  padding: 0;
  margin: 18px 0 0;
}
.chips li {
  font-size: .87rem;
  color: var(--cream);
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 6px 12px;
}

/* ----------------------------------------------------------------- faq --- */

.faq { max-width: 800px; }
.faq details {
  border-bottom: 1px solid var(--line-soft);
}
.faq summary {
  cursor: pointer;
  list-style: none;
  padding: 20px 40px 20px 0;
  font-weight: 700;
  font-size: 1.02rem;
  position: relative;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: "";
  position: absolute;
  right: 6px; top: 50%;
  width: 11px; height: 11px;
  border-right: 2px solid var(--gold-deep);
  border-bottom: 2px solid var(--gold-deep);
  transform: translateY(-70%) rotate(45deg);
  transition: transform .2s ease;
}
.faq details[open] summary::after { transform: translateY(-30%) rotate(-135deg); }
.faq details p {
  color: var(--muted);
  margin: 0 0 20px;
  max-width: 68ch;
  font-size: .97rem;
}
/* The unlock answer is a list of prices; a list reads faster than a run-on
   sentence, and this is the only place in the FAQ that needs one. */
.faq details ul {
  color: var(--muted);
  margin: 0 0 20px;
  padding-left: 20px;
  max-width: 68ch;
  font-size: .97rem;
}
.faq details li { margin: 0 0 7px; }
.faq details li b { color: var(--cream); }

/* -------------------------------------------------------------- footer --- */

.cta-band { padding-bottom: clamp(56px, 8vw, 96px); }
.cta-band .panel { text-align: center; }
.cta-band .hero-cta { justify-content: center; margin-bottom: 0; }

.site-foot {
  border-top: 1px solid var(--line-soft);
  padding: 40px 0 56px;
  color: var(--muted-dim);
  font-size: .9rem;
}
.site-foot .wrap {
  display: flex;
  flex-wrap: wrap;
  gap: 16px 28px;
  align-items: center;
}
.site-foot nav {
  margin-left: auto;
  display: flex;
  flex-wrap: wrap;
  gap: 22px;
}
.site-foot nav a {
  color: var(--muted);
  padding: 6px 0;          /* a 36 px tall tap target on a phone */
  display: inline-block;
}
.site-foot a { color: var(--muted); }
.site-foot .studio {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  color: var(--muted-dim);
  text-decoration: none;
}
.site-foot .studio:hover { color: var(--muted); }
.site-foot .studio img { width: 20px; height: 20px; border-radius: 5px; }
.site-foot .fine {
  flex: 1 0 100%;
  margin-top: 8px;
  font-size: .82rem;
  color: var(--muted-dim);
  max-width: 76ch;
}

/* ------------------------------------------------------- legal / prose --- */

.prose {
  max-width: 760px;
  margin: 0 auto;
}
.prose h2 {
  font-size: 1.3rem;
  margin-top: 44px;
  padding-top: 6px;
  scroll-margin-top: 96px;
}
.prose h2:first-of-type { margin-top: 24px; }
.prose p, .prose li { color: var(--muted); }
.prose strong { color: var(--cream); font-weight: 700; }
.prose ul { padding-left: 20px; }
.prose li { margin-bottom: .5em; }

/* The privacy policy's summary table. Wide content must scroll inside its own
   box, never make the page scroll sideways on a phone. */

.data-table {
  width: 100%;
  border-collapse: collapse;
  margin: 0 0 28px;
  font-size: .92rem;
  display: block;
  overflow-x: auto;
  white-space: nowrap;
}
.data-table th,
.data-table td {
  border-bottom: 1px solid var(--line-soft);
  padding: 11px 16px 11px 0;
  text-align: left;
  vertical-align: top;
  color: var(--muted);
}
.data-table th {
  color: var(--cream);
  font-weight: 700;
  font-size: .88rem;
  border-bottom-color: var(--line);
}
.data-table td strong { color: var(--cream); }
@media (min-width: 720px) {
  .data-table { display: table; white-space: normal; }
  .data-table td { max-width: 22ch; }
}

.note {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 20px 24px;
  margin: 26px 0 8px;
}
.note p:last-child { margin-bottom: 0; }
.note p { color: var(--cream); }

.toc {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 20px 24px;
  margin: 30px 0;
}
.toc b {
  display: block;
  font-size: .95rem;
  color: var(--cream);
  margin-bottom: 12px;
}
.toc ol {
  margin: 0;
  padding-left: 20px;
  columns: 2;
  column-gap: 30px;
  font-size: .93rem;
}
.toc li { margin-bottom: 6px; break-inside: avoid; }
.toc a { color: var(--muted); }
.toc a:hover { color: var(--gold); }
@media (max-width: 560px) { .toc ol { columns: 1; } }

.meta-row {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 22px;
  font-size: .87rem;
  color: var(--muted-dim);
  padding-bottom: 8px;
}

/* ==========================================================================
   Bangla
   Bangla is a joined script: letter-spacing pulls the conjuncts apart and the
   headline tracking looks broken. Turn all tracking off, and give the text a
   little more room for the matras above and below the line.
   ========================================================================== */

html[lang="bn"] body { line-height: 1.8; }

html[lang="bn"] h1,
html[lang="bn"] h2,
html[lang="bn"] h3,
html[lang="bn"] .btn,
html[lang="bn"] .brand { letter-spacing: normal; }

html[lang="bn"] h1,
html[lang="bn"] h2 { line-height: 1.35; }

html[lang="bn"] .demo-title,
html[lang="bn"] .stat span {
  letter-spacing: normal;
  text-transform: none;
  font-size: .82rem;
}

html[lang="bn"] .stat span { font-size: .68rem; }

/* the framed screenshots carry English captions of their own */
html[lang="bn"] .shots figcaption { font-size: .82rem; }

/* --------------------------------------------------------- inline links --- */
/* Gold on cream is only a 1.02:1 difference — colour alone is not enough to
   mark a link inside a paragraph, so underline the ones that sit in prose. */
.prose p a,
.prose li a,
.faq p a,
.card p a,
.split p a:not(.btn) {
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: .18em;
}
.prose p a:hover,
.faq p a:hover { text-decoration-thickness: 2px; }

/* ==========================================================================
   The playable demo — Ash's own materials
   The tray, the wells and the marbles are lib/app/theme.dart's Palette.ash,
   and the marble is the cat's eye, the form the app opens on. The rules it
   plays are the app's: a marble travels through empty wells only, four of
   one colour in a line clears with the slants counted, a move that clears
   nothing lets two new marbles land, and the tray filling ends it.
   ========================================================================== */

.tray {
  --side: 7;
  position: relative;
  display: grid;
  grid-template-columns: repeat(var(--side), 1fr);
  gap: 2.2%;
  padding: 3.4%;
  aspect-ratio: 1;
  background: var(--board);
  border: 3px solid var(--rim, #c6b593);
  border-radius: 6%;
  box-shadow: var(--shadow-md), inset 0 1px 0 rgba(255, 255, 255, .5);
  touch-action: manipulation;
  container-type: inline-size;
}

/* The grain: the same stripes the tray bakes, a few degrees off vertical. */
.tray::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 4%;
  pointer-events: none;
  background: repeating-linear-gradient(97deg,
    rgba(50, 41, 30, .055) 0 2px, rgba(50, 41, 30, 0) 2px 13px);
}

.well {
  position: relative;
  aspect-ratio: 1;
  border-radius: 50%;
  background: var(--cell);
  box-shadow: inset 0 2px 3px rgba(58, 44, 28, .28),
              inset 0 -1px 0 rgba(255, 255, 255, .45);
  cursor: default;
}
.well.can { cursor: pointer; }

/* A well the picked marble can roll to: a thin ring, the app's `reach`. */
.well.reach::after {
  content: "";
  position: absolute;
  inset: 22%;
  border-radius: 50%;
  border: 2px solid rgba(50, 41, 30, .38);
}

.marble {
  --m: #999;
  position: absolute;
  inset: 7%;
  border-radius: 50%;
  overflow: hidden;
  cursor: pointer;
  background: radial-gradient(circle at 44% 41%,
    color-mix(in srgb, var(--m) 74%, #fff) 0,
    var(--m) 55%,
    color-mix(in srgb, var(--m) 60%, #000) 100%);
  box-shadow: 0 2px 2px rgba(58, 44, 28, .3);
  transition: transform .13s cubic-bezier(.33, 1, .68, 1),
              box-shadow .13s cubic-bezier(.33, 1, .68, 1);
}
/* The vane: a lens turned -35deg, in the marble's OWN colour run lighter.
   Never a second hue — a row of four has to still read as four of one. */
.marble::after {
  content: "";
  position: absolute;
  left: 7%; right: 7%; top: 27%; bottom: 27%;
  border-radius: 50%;
  transform: rotate(-35deg);
  filter: blur(1px);
  background: radial-gradient(ellipse at 50% 50%,
    color-mix(in srgb, var(--m) 25%, #fff) 0 22%,
    color-mix(in srgb, var(--m) 55%, #fff) 58%,
    transparent 100%);
}
.marble::before {
  content: "";
  position: absolute;
  left: 15%; top: 13%; width: 19%; height: 19%;
  border-radius: 50%;
  background: rgba(255, 255, 255, .85);
  filter: blur(1.2px);
  z-index: 1;
}
.well.picked .marble {
  transform: translateY(-7%) scale(1.07);
  box-shadow: 0 7px 7px rgba(58, 44, 28, .26);
}

/* The marbles coming next, shown small in the well they will land in. */
.ghost {
  position: absolute;
  inset: 34%;
  border-radius: 50%;
  background: var(--m);
  opacity: .5;
  pointer-events: none;
}

.demo-top {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 12px;
  flex-wrap: wrap;
}
.demo-title { font-weight: 700; margin-right: auto; }
.demo-next {
  display: inline-flex;
  gap: 8px;
  align-items: center;
  font-size: 13px;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--muted-dim);
}
/* The dots live in an inner span, so that span has to lay them out too:
   an <i> is inline, and width and height do nothing to an inline box. */
.demo-next > span {
  display: inline-flex;
  gap: 6px;
  align-items: center;
}
.demo-next i {
  display: inline-block;
  width: 15px; height: 15px;
  border-radius: 50%;
  background: var(--m, #999);
  box-shadow: inset 0 -2px 3px rgba(0, 0, 0, .18);
}
.demo-hint {
  display: flex;
  align-items: baseline;
  gap: 12px;
  margin: 12px 0 0;
  font-size: 15px;
  color: var(--muted-dim);
  min-height: 1.6em;
}
.demo-hint > span { min-width: 0; }
.demo-hint button {
  /* Never squeezed and never clipped: Bangla's "নতুন ট্রে" is wider than
     "New tray", and as a flex item it shrank until the last letter was
     cut off. */
  flex: 0 0 auto;
  min-width: max-content;
  margin-left: auto;
  font: inherit;
  font-weight: 700;
  color: var(--gold);
  background: none;
  border: 0;
  padding: 4px 2px;
  cursor: pointer;
  text-decoration: underline;
  white-space: nowrap;
}
/* Bangla needs room the browser does not ask for. Chrome measured
   "নতুন ট্রে" at 50 px in the system fallback and then painted about
   105 px of it, so the last glyph ran off the panel. There is no Bangla
   face in the stack to measure against; until there is, the button is
   given the width by hand. */
:lang(bn) .demo-hint button { min-width: 7.5em; text-align: left; }

/* On a phone the demo's top row is four things on one line, and the
   Bangla title alone is most of that line. Give the title the whole
   first line and let Next, Score and Best share the second. */
@media (max-width: 560px) {
  .demo-title { flex: 1 0 100%; margin-right: 0; }
  .demo-top { gap: 10px; }
  .demo-top .stat { flex: 1 1 auto; }
  .demo-next { margin-right: auto; }
}

/* -------------------------------------------------------------- viewer --- */
/* One screen of the strip, large, in a native <dialog>. Its own dark
   ground whatever the page's palette: a lightbox is a cinema, not a page.
   Built by site.js on first use; with no JS there is no viewer and the
   strip is a plain row of pictures. */

.shots img { cursor: zoom-in; }

html:has(.shot-viewer[open]) { overflow: hidden; }

.shot-viewer {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: none;
  max-height: none;
  margin: 0;
  padding: 0;
  border: 0;
  background: #0c0c0e;
  color: #ededf0;
}
.shot-viewer::backdrop { background: #0c0c0e; }
.shot-viewer[open] {
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto;
}

.sv-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 10px clamp(16px, 4vw, 32px);
  border-bottom: 1px solid rgba(255, 255, 255, .12);
}
.sv-count { margin: 0; font-size: .95rem; color: #b6b6c0; }

.shot-viewer button {
  display: inline-grid;
  place-items: center;
  min-width: 44px;
  height: 44px;
  padding: 0 14px;
  border: 1px solid rgba(255, 255, 255, .28);
  border-radius: 10px;
  background: none;
  color: #ededf0;
  font-family: inherit;
  font-size: .95rem;
  font-weight: 600;
  line-height: 1;
  cursor: pointer;
}
.shot-viewer button:hover { border-color: #b6b6c0; background: rgba(255, 255, 255, .06); }
.sv-arrow { padding: 0 !important; }
.sv-arrow svg {
  width: 20px; height: 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.sv-stage {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  padding: 16px clamp(16px, 4vw, 32px);
  min-height: 0;
}
.sv-stage img {
  margin: auto;
  width: auto;
  height: auto;
  /* Never larger than the file: a stretched screenshot is a blur. */
  max-width: min(100%, 540px);
  max-height: calc(100vh - 190px);
  max-height: calc(100dvh - 190px);
  border-radius: 10px;
  border: 0;
}

.sv-cap {
  margin: 0 auto;
  padding: 0 clamp(16px, 4vw, 32px) 22px;
  max-width: 64ch;
  min-height: 3.2em;
  text-align: center;
  color: #b6b6c0;
  font-size: .95rem;
  line-height: 1.5;
}

/* On a phone the arrows move under the picture, where a thumb is. */
@media (max-width: 620px) {
  .sv-stage { grid-template-columns: 1fr 1fr; gap: 12px; }
  .sv-stage img { grid-column: 1 / -1; grid-row: 1; max-height: calc(100vh - 250px); max-height: calc(100dvh - 250px); }
  .sv-arrow { grid-row: 2; width: 100%; }
}
