/* ============================================================================
   book.css — pasakeles.lt landing page
   ----------------------------------------------------------------------------
   Loaded after scrollcraft.css. Rebrands the six colour roles and two
   families, then styles this page's own markup. Never restyles .sc-stage,
   .sc-copy or any [data-sc-*] selector — those stay the engine's.

   Grammar: chaptered editorial (scroll-craft references/uniqueness.md §2.2).
   Hard cuts between chapters, so each .ch below paints its own opaque ground
   rather than using data-sc-drift (devices.md §10: drift is for pages that
   are one continuous place; a cut is not an interpolation).
   ========================================================================== */

/* Self-hosted, not the Google Fonts CDN: this app handles children's data
   under GDPR, so no third-party request should carry a parent's IP on every
   page load.

   Fraunces is ONE file per style, not Google's latin + latin-ext pair, and
   that is load-bearing rather than tidiness. Google's `latin` subset carries
   ASCII `u` but not `ū`; when `ū` sits beside an ASCII letter — which in
   Lithuanian is almost always — Chromium shapes the run with the latin face,
   HarfBuzz cannot find U+016B in it, and falls back to decomposing it into
   u + U+0304. Fraunces maps U+0304 to `macroncmb`, which carries an advance
   of 820 units instead of the 0 a combining mark needs, so the macron was
   drawn as a spacing glyph landing on top of the FOLLOWING letter: "jūsų"
   came out as "jusū̄ų" in every heading on the site. One file covering both
   ranges means the run never splits and U+016B always resolves to the
   precomposed glyph. Rebuild with tools/build_webfonts.py.

   Literata keeps Google's split: its U+0304 has a 0 advance, so the same
   decomposition path stacks correctly there and the bug never appears.

   Both are variable fonts covering the whole weight axis in one file, so a
   single @font-face per style covers every weight this page uses. */
@font-face {
  font-family: "Fraunces";
  font-style: normal; font-weight: 400 700; font-display: swap;
  src: url("fonts/fraunces.woff2") format("woff2");
}
@font-face {
  font-family: "Fraunces";
  font-style: italic; font-weight: 400 700; font-display: swap;
  src: url("fonts/fraunces-italic.woff2") format("woff2");
}
/* latin-ext is listed first so it wins the cascade for the Lithuanian
   diacritics (ą č ę ė į š ų ū ž). */
@font-face {
  font-family: "Literata";
  font-style: normal; font-weight: 400 600; font-display: swap;
  src: url("fonts/literata-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Literata";
  font-style: normal; font-weight: 400 600; font-display: swap;
  src: url("fonts/literata-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  /* --- colour roles. Paper, ink, one accent spent on exactly one job: the
         child's name. Values chosen and contrast-checked against the actual
         renders (see BRIEF.md's "cannot be verified" note — computed from
         these hex values, not measured on a live render). ------------------ */
  --sc-canvas:      #f4ecd8;
  --sc-surface:     #ead9ba;
  --sc-ink:         #1b2f52;
  --sc-ink-soft:    #4a5d82;
  --sc-accent:      #a8402e;
  --sc-accent-ink:  #f4ecd8;

  --sc-hairline:        color-mix(in oklab, var(--sc-ink) 16%, transparent);
  --sc-hairline-strong: color-mix(in oklab, var(--sc-ink) 30%, transparent);

  /* The dark inversion, used only inside the story chapter (the peak). One
     hue, two lightnesses — the exception taste.md grants a page that hard-cuts
     between light and dark grounds. */
  --book-dark-canvas: #0f1c38;
  --book-dark-ink:    #f4ecd8;
  --book-dark-soft:   #b9c3dd;
  --book-dark-accent: #e2836f;

  --sc-font-display: "Fraunces", "Iowan Old Style", "Georgia", serif;
  --sc-font-text:    "Literata", "Iowan Old Style", "Georgia", serif;

  /* Shadows tinted warm, toward the paper, not the default cool near-black. */
  --sc-shadow-color: 28 32% 10%;

  --sc-r-sm: 3px; --sc-r-md: 6px; --sc-r-lg: 10px; --sc-r-pill: 999px;
}

/* --------------------------------------------------------------- reset --- */
.book { background: var(--sc-canvas); }
.book :is(h1, h2, h3) { font-family: var(--sc-font-display); }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}
.skip {
  position: absolute; z-index: 100; top: -3rem; left: var(--sc-4);
  background: var(--sc-ink); color: var(--sc-canvas);
  padding: var(--sc-3) var(--sc-5); border-radius: var(--sc-r-sm);
  text-decoration: none; transition: top var(--sc-d-base) var(--sc-ease-out);
}
.skip:focus { top: var(--sc-4); }

/* Each chapter is a full opaque cut, per devices.md §10's guidance for a
   chaptered page: paint grounds per section, do not interpolate between them. */
.ch { position: relative; background: var(--sc-canvas); color: var(--sc-ink); }
/* Chapters with a page-turn wrapper wide enough to have real lateral reach
   under rotateY (see the page-turn section) clip that reach to their own
   width. Never applied to .ch--story or .ch--imprint: both hold a
   position:sticky stage, and overflow other than visible on an ancestor
   changes what a sticky element sticks relative to — those two instead keep
   their turning element narrow (see .story__turn and .imprint__inner). */
.ch--hour, .ch--rest, .ch--method, .ch--price { overflow: hidden; }

/* ------------------------------------------------------------------ folio --
   The nav for this grammar: no fixed bar, a folio in the margin instead.
   Updated by book.js as chapters cross the reading line. */
.folio {
  position: fixed; z-index: var(--sc-z-chrome);
  left: var(--sc-gutter); top: var(--sc-6);
  display: flex; gap: var(--sc-2); align-items: baseline;
  font-family: var(--sc-font-text); font-size: var(--sc-t-xs);
  letter-spacing: var(--sc-track-wide); text-transform: uppercase;
  color: var(--sc-ink-soft);
  pointer-events: none;
  transition: opacity var(--sc-d-slow) var(--sc-ease-out);
}
.folio[hidden] { display: flex; opacity: 0; }
.folio:not([hidden]) { opacity: 1; }
.folio__num { font-family: var(--sc-font-display); font-style: italic; }
.folio__title::before { content: "· "; }
/* The peak prints its own chapter mark and title into the top-left of its
   stage, in the exact spot this folio occupies — they collided, and the folio
   was saying the same words ("II · Ežiuko durelės") twice over. It stands
   down for any chapter marked [data-folio-hide]; book.js does the toggling.
   :not([hidden]) is carried along so this beats the .folio:not([hidden])
   rule above rather than tying with it. */
.folio.is-muted:not([hidden]) { opacity: 0; }

.blank { position: relative; display: inline-flex; }
.blank input {
  font: inherit; font-style: normal; color: var(--sc-accent);
  background: transparent; border: 0; border-bottom: 1px solid var(--sc-hairline-strong);
  padding: 0 var(--sc-1) var(--sc-1);
  width: 11ch; min-width: 6ch;
  text-align: center;
  transition: border-color var(--sc-d-base) var(--sc-ease-out);
}
/* Placeholders stay visible: the email field's "jusu@pastas.lt" is the only
   indication of what belongs there, and a blanket rule here previously
   suppressed it along with the name field's (which has no placeholder of
   its own — the label "Įveskite vaiko vardą" carries that job instead).
   Tinted from the ink, not browser-default gray (taste.md: no flat gray). */
.blank input::placeholder {
  color: color-mix(in oklab, var(--sc-ink) 42%, transparent);
  font-style: italic;
}
.blank input:hover { border-color: var(--sc-ink-soft); }
.blank input:focus-visible {
  outline: 2px solid var(--sc-accent); outline-offset: 4px;
  border-radius: var(--sc-r-sm); border-color: transparent;
}
.book[data-has-name] .blank input { border-color: var(--sc-accent); }

/* ================================================================ 0 · HERO
   The illustrated title page. The plate's own ground is the same deep navy as
   this section's, so the picture has no visible edge: it dissolves into the
   page instead of sitting on it as a rectangle. That seam is the whole trick,
   and it is why the ground below is a sampled value from the JPEG (#062c4d,
   measured off the plate's border pixels) rather than --book-dark-canvas. */
.hero {
  position: relative;
  min-height: 100svh;
  display: grid; grid-template-rows: auto 1fr;
  background: #062c4d;
  color: var(--book-dark-ink);
  overflow: hidden;
}

/* Narrow viewports stack: type on solid ground first, then the plate filling
   whatever height is left. An earlier pass overlaid the type on a scrimmed
   full-bleed plate instead, which put "Įveskite vaiko vardą" and the blank —
   the hook — on top of the lit bedspread at 375x667, cream on cream. The
   plate's own top edge is the same navy as the ground above it, so the seam
   between the two rows is invisible even though the layout is stacked. */
.hero__art { grid-row: 2; position: relative; min-height: 34svh; }
.hero__plate {
  display: block; width: 100%; height: 100%;
  object-fit: cover; object-position: 46% 50%;
  /* The plate arrives already in motion: a slow settle, not a slide-in. */
  animation: hero-settle 1600ms var(--sc-ease-out) both;
}

/* The lamp is the emotional centre of the picture, so it is the one thing on
   this page that is alive. A single warm radial over the lamp's own glow,
   breathing on a 9s cycle — slower than a breath, well under the threshold
   where motion starts competing with the type for attention. */
.hero__lamp {
  position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(38% 46% at 38% 46%,
              rgba(255, 208, 138, 0.30), rgba(255, 208, 138, 0) 70%);
  mix-blend-mode: screen;
  animation: hero-breathe 9s ease-in-out 1200ms infinite;
}

.hero__copy {
  grid-row: 1;
  position: relative; z-index: 1;
  padding: var(--sc-7) var(--sc-gutter) var(--sc-6);
  max-width: 42rem;
  text-align: center; margin-inline: auto;
}

.hero__title {
  font-weight: 500;
  /* Capped below the title page's 5.4rem: this one shares its screen with a
     picture, and a two-line name set at 86px crowded it on 1512-wide. */
  font-size: clamp(2.35rem, 1.9rem + 2.7vw, 4rem);
  line-height: var(--sc-leading-tight);
  letter-spacing: var(--sc-track-tight);
  text-wrap: balance;
  margin: 0 0 var(--sc-5);
  color: var(--book-dark-ink);
  /* A 24-character name is allowed by the input's maxlength, and the genitive
     adds up to two more. .is-long (set by the JS below) covers the ordinary
     long names; this is the last resort that keeps even an absurd one inside
     the column instead of overflowing the page. */
  overflow-wrap: break-word;
}
.hero__title.is-long { font-size: clamp(1.9rem, 1.5rem + 2vw, 3rem); }
.hero__title-in { display: inline-block; animation: hero-rise 900ms var(--sc-ease-out) 160ms both; }
/* Fired once, when the blank goes from empty to filled: the title re-sets
   itself in the reader's own child's name. Ink settling, not a slide. */
.hero__title.is-inking .hero__title-in { animation: hero-ink 620ms var(--sc-ease-out) both; }

.hero__sub {
  font-size: var(--sc-t-lg); color: var(--book-dark-soft);
  line-height: 1.5; max-width: 34ch; margin: 0 auto var(--sc-7);
  text-wrap: pretty;
  animation: hero-rise 900ms var(--sc-ease-out) 320ms both;
}

.hero__ded { margin: 0; animation: hero-rise 900ms var(--sc-ease-out) 460ms both; }
.hero__ded-line {
  font-family: var(--sc-font-display); font-style: italic;
  font-size: var(--sc-t-xl); line-height: 1.6;
  display: inline-flex; flex-wrap: wrap; gap: 0 var(--sc-2);
  align-items: baseline; justify-content: center;
  color: var(--book-dark-ink);
}
.blank--dark input {
  color: var(--book-dark-accent);
  border-bottom-color: color-mix(in oklab, var(--book-dark-ink) 34%, transparent);
}
.blank--dark input:hover { border-bottom-color: var(--book-dark-soft); }
.blank--dark input:focus-visible { outline-color: var(--book-dark-accent); }
.book[data-has-name] .blank--dark input { border-bottom-color: var(--book-dark-accent); }

/* Only shown when the name could not be declined and the title therefore
   stayed generic — otherwise the title itself is the confirmation and this
   line would just say the same thing twice. */
.hero__confirm {
  display: block; overflow: hidden;
  margin-top: 0; max-height: 0; opacity: 0;
  font-family: var(--sc-font-text); font-style: italic;
  font-size: var(--sc-t-sm); color: var(--book-dark-soft);
  transition: opacity var(--sc-d-slow) var(--sc-ease-out),
              margin-top var(--sc-d-slow) var(--sc-ease-out),
              max-height var(--sc-d-slow) var(--sc-ease-out);
}
.book[data-fallback-name] .hero__confirm {
  margin-top: var(--sc-3); max-height: 3em; opacity: 1;
}
.hero .name-slot { color: var(--book-dark-accent); }
.hero .name-slot__rule { border-bottom-color: color-mix(in oklab, var(--book-dark-ink) 40%, transparent); }

@keyframes hero-settle { from { transform: scale(1.055); } to { transform: scale(1); } }
@keyframes hero-rise   { from { opacity: 0; transform: translateY(0.7rem); } to { opacity: 1; transform: none; } }
@keyframes hero-ink    { from { opacity: 0; filter: blur(5px); } to { opacity: 1; filter: none; } }
@keyframes hero-breathe {
  0%, 100% { opacity: 0.45; }
  50%      { opacity: 1; }
}

/* Wide viewports: the plate keeps the right of the frame and the type takes
   the left, where the plate's own ground is unbroken navy. The scrim turns
   horizontal so the seam runs down the page instead of across it. */
@media (min-width: 62rem) {
  .hero { grid-template-rows: none; align-items: center; }
  /* Wide enough that the plate can hold the right of the frame at full height
     and the type can sit over its unbroken navy wall on the left. */
  /* 55%, not the ~78% an earlier pass used: at 78% the plate's lamp glow and
     the copy column landed on the same part of the screen, and measuring the
     rendered pixels put the sub-heading at 3.3:1 against it. No scrim can fix
     that — the fade would have to reach across the glow, dimming the one
     thing the picture is here for. Narrowing the plate moves the glow clear
     of the type instead, and the crop this forces costs only the outer edges
     of the room. */
  .hero__art {
    grid-row: 1; grid-column: 1;
    position: absolute; inset: 0 0 0 auto; width: 55%; min-height: 0;
    /* The plate's left edge feathers into the ground rather than being dimmed
       by an overlay: at this crop that edge is the room's navy wall, so the
       two are the same colour and the seam disappears. */
    -webkit-mask-image: linear-gradient(90deg, transparent 0%, #000 13%);
            mask-image: linear-gradient(90deg, transparent 0%, #000 13%);
  }
  /* Kept as insurance for crops that land on something brighter than the
     wall; it is short enough to end well before the glow. */
  .hero__art::after {
    content: ""; position: absolute; inset: 0; pointer-events: none;
    background: linear-gradient(90deg,
      rgba(6, 44, 77, 0.85) 0%, rgba(6, 44, 77, 0) 18%);
  }
  .hero__plate { object-position: 55% 55%; }
  .hero__copy {
    grid-row: 1; grid-column: 1;
    justify-self: start;
    width: min(44%, 34rem); max-width: none;
    text-align: left; margin-inline: 0;
    padding-block: var(--sc-9);
    /* Beyond a 100rem frame the type would otherwise be stranded against the
       left edge, half a screen away from the picture it belongs to. This
       centres the whole composition in a 100rem band instead. */
    margin-left: max(0px, calc((100vw - 100rem) / 2));
  }
  .hero__sub { margin-inline: 0; }
  .hero__ded-line { justify-content: flex-start; }
}

@media (min-width: 100rem) { .hero__art { width: 62%; } }


/* Short viewports — a 375x667 phone, and any 720p-class laptop. Without this
   the opening is taller than the fold and the blank drops below it, which is
   the one thing this whole section exists to prevent. Only the spacing gives
   way; nothing is hidden and no type shrinks. */
@media (max-height: 780px) {
  .hero__copy { padding-top: var(--sc-5); padding-bottom: var(--sc-4); }
  .hero__title { margin-bottom: var(--sc-4); }
  .hero__sub { margin-bottom: var(--sc-5); }
  .hero__art { min-height: 30svh; }
}

@media (prefers-reduced-motion: reduce) {
  .hero__plate, .hero__lamp, .hero__title-in, .hero__sub, .hero__ded,
  .hero__title.is-inking .hero__title-in { animation: none; }
  .hero__lamp { opacity: 0.7; }
}

/* ================================================================== LOGIN
   A single quiet page, not a chapter of the book: same ground and type as
   the title page, a narrower measure since there is only one line of
   copy and one form to hold. Reuses .ask/.blank/.ask__go from the imprint
   verbatim rather than redefining a second form style. */
.ch--notice { display: grid; place-items: center; min-height: 100svh; }
.notice { width: 100%; max-width: 32rem; padding: var(--sc-9) var(--sc-gutter); text-align: center; }
.notice__mark {
  color: var(--sc-ink-soft); display: flex; justify-content: center;
  margin-bottom: var(--sc-6);
  transition: color var(--sc-d-base) var(--sc-ease-out);
}
.notice__mark:hover { color: var(--sc-accent); }
.notice__mark:focus-visible { outline: 2px solid var(--sc-accent); outline-offset: 4px; border-radius: var(--sc-r-sm); }
.notice__title {
  font-weight: 500;
  /* Not --sc-t-3xl: that token is a hero/chapter size, built to keep
     scaling up to 5rem as the viewport widens, on the assumption that its
     container scales with it. .notice is deliberately narrow and fixed
     (a single centered message, not a chapter), so on a wide desktop
     screen the hero clamp kept growing while the box did not, wrapping a
     two- or three-word heading into a tall stack of near-single-word
     lines — reading exactly like a mobile layout stretched onto a big
     screen. This clamp's ceiling is sized to what the widened box above
     can actually hold on one or two lines. */
  font-size: clamp(1.85rem, 1.5rem + 1.6vw, 2.75rem);
  line-height: var(--sc-leading-tight); margin: 0 0 var(--sc-4);
}
.notice__sub { color: var(--sc-ink-soft); max-width: 34ch; margin: 0 auto var(--sc-8); text-wrap: pretty; }
/* The login form's own button, not the shared .ask__go default (which stays
   inline for the imprint's running-text CTA on the landing page): dropped
   to its own row, a line or two below the email field, rather than sitting
   immediately beside it. */
.notice .ask__go { display: block; margin: var(--sc-6) auto 0; }
.notice__foot { margin-top: var(--sc-7); font-size: var(--sc-t-sm); color: var(--sc-ink-soft); }
.notice__foot a {
  color: var(--sc-ink); text-decoration-color: var(--sc-hairline-strong);
  text-underline-offset: 0.2em;
  transition: color 140ms var(--sc-ease-out);
}
.notice__foot a:hover { color: var(--sc-accent); }
.notice__foot a:focus-visible { outline: 2px solid var(--sc-accent); outline-offset: 3px; border-radius: var(--sc-r-sm); }

/* ================================================================ SPREADS
   Chapters I and III: flow + in, with the plate in its own column and a
   caption. Media never bleeds under type in this grammar. */
.spread {
  max-width: var(--sc-maxw); margin-inline: auto;
  /* Asymmetric on purpose: --sc-10 (8rem) at the top gives the chapter a
     real breath as it opens, but the same amount at the bottom compounded
     with .ch--rest's own deliberate emptiness right after it (see below)
     into a stretch that read as excessive rather than intentional. Only
     the close shrinks. */
  padding-block: var(--sc-10) var(--sc-6);
  padding-inline: var(--sc-gutter);
  display: flex; flex-direction: column; gap: var(--sc-8);
}
/* width:100% matters as much as the max-width. .spread is a column flex
   container, and `margin-inline:auto` on a flex item makes it size to its
   CONTENT instead of stretching — so without this each chapter's column was
   as wide as its own longest line (647px in chapter I, 592px in chapter III)
   and every chapter opened at a different x. They are one measure now, which
   is what lets the chapter marks line up down the page. */
.spread__text { width: 100%; max-width: 46rem; margin-inline: auto; }

.chapter-mark {
  font-family: var(--sc-font-text); font-size: var(--sc-t-xs);
  letter-spacing: var(--sc-track-wide); text-transform: uppercase;
  color: var(--sc-ink-soft); margin: 0 0 var(--sc-3);
}
.chapter-title {
  font-weight: 500; font-size: var(--sc-t-3xl);
  line-height: var(--sc-leading-tight); margin: 0 0 var(--sc-5);
}
.lede { font-size: var(--sc-t-lg); line-height: 1.5; color: var(--sc-ink); max-width: 42ch; margin: 0 0 var(--sc-6); text-wrap: pretty; }
.prose { max-width: var(--sc-measure); color: var(--sc-ink-soft); line-height: var(--sc-leading-body); text-wrap: pretty; }
.prose + .prose { margin-top: var(--sc-4); }

.plate { margin: 0; }
.plate__frame {
  overflow: clip; border-radius: var(--sc-r-md);
  box-shadow: var(--sc-e2); border: 1px solid var(--sc-hairline);
}
.plate__frame img { width: 100%; height: auto; display: block; }
/* The two Chapter-I/III plates, made large and dominant: full spread width,
   a tall generous frame with the image covering it rather than dictating the
   frame's own aspect ratio. */
.plate--wide .plate__frame {
  height: min(78vh, 640px);
}
.plate--wide .plate__frame img {
  width: 100%; height: 100%; object-fit: cover;
}

.steps { list-style: none; margin: var(--sc-7) 0 0; padding: 0; counter-reset: step; }
.steps li { counter-increment: step; position: relative; padding-left: var(--sc-8); }
.steps li + li { margin-top: var(--sc-6); }
.steps li::before {
  content: counter(step);
  position: absolute; left: 0; top: 0.15em;
  width: 1.6rem; height: 1.6rem; border-radius: var(--sc-r-pill);
  border: 1px solid var(--sc-hairline-strong);
  display: grid; place-items: center;
  font-family: var(--sc-font-display); font-style: italic; font-size: var(--sc-t-sm);
  color: var(--sc-ink-soft);
}
.steps h3 { font-size: var(--sc-t-base); font-weight: 600; margin: 0 0 var(--sc-1); }
.steps p { margin: 0; color: var(--sc-ink-soft); max-width: 40ch; }

/* ===================================================================== REST
   The authored silence before the peak. Ground only, nothing else — see
   BRIEF.md's feeling curve. Not dead scroll: the intent is on the page. */
/* The silence before the peak. The mark is centred in it, so HALF this height
   lands in the gap after chapter I's closing line — which is what actually
   made that gap read as dead space rather than as a pause, far more than the
   .spread padding above did. Capped in rem as well as svh because a tall
   viewport (a 1112px tablet) otherwise scales the emptiness up with it: 62svh
   there was 689px, i.e. a 406px gap on its own. */
.ch--rest { display: grid; place-items: center; min-height: min(30svh, 15rem); }
.dinkus { color: var(--sc-hairline-strong); opacity: 0.7; }
.dinkus svg { display: block; }

/* ==================================================================== PEAK
   Chapter II. Inverts to the dark ground — the one moment on the page that
   does, which is what makes it read as the peak rather than as decoration. */
.ch--story { background: var(--book-dark-canvas); color: var(--book-dark-ink); }
.stage.story { display: grid; }
.story__plate {
  position: absolute; inset: 0; z-index: 0;
  width: 100%; height: 100%; overflow: clip;
}
.story__plate img { width: 100%; height: 100%; object-fit: cover; }
/* A column of density under the text column (taste.md's third scrim shape),
   not a full-frame overlay: the right half of the plate keeps its contrast. */
.story__veil {
  position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: linear-gradient(90deg,
    color-mix(in oklab, var(--book-dark-canvas) 88%, transparent) 0%,
    color-mix(in oklab, var(--book-dark-canvas) 60%, transparent) 34%,
    color-mix(in oklab, var(--book-dark-canvas) 12%, transparent) 58%,
    transparent 72%);
}
/* Wraps .story__col to carry the one-shot page-turn entrance (below) without
   fighting the continuous, transition-free scroll-driven fade that
   .story__col itself needs — see the page-turn section for why these two
   have to live on separate elements. Sized to its content (matching
   .story__col's own 34rem) rather than stretching to the grid cell's full
   width: .stage.story has no place-items, so a stretched wrapper would be
   viewport-wide, and rotating a viewport-wide box under rotateY reaches
   hundreds of pixels past the edge in its pre-turn state. This element sits
   inside a position:sticky ancestor, so it is kept narrow instead of relying
   on overflow-x:clip the way the non-pinned chapters below do. */
.story__turn { position: relative; z-index: 2; justify-self: start; width: fit-content; max-width: 34rem; }

.story__col {
  max-width: 34rem;
  /* Block padding is small and fixed, not --sc-10: the whole accumulated
     text stack has to fit inside one fixed-height (100vh) pinned stage with
     overflow:clip, and generous vertical padding was eating into that
     budget. See .story__text p for the rest of the fit fix. */
  padding-block: var(--sc-6); padding-inline: var(--sc-gutter);
  /* The bespoke exit: the whole accumulated page fades together in the last
     sliver of the pin's own progress, driven straight off --sc-p per
     devices.md ("anything the kit does not cover, drive from CSS with
     calc()"). This is what keeps the accumulate-and-hold cues below from
     bleeding into Chapter III during the unpin slide (devices.md §2, "only
     the last act may hold"): by p=1 this wrapper is already at opacity 0.
     No transition here on purpose: a scroll-driven value must track --sc-p
     1:1, and a CSS transition would make it lag every animation frame. */
  opacity: clamp(0, calc((1 - var(--sc-p, 0)) * 14), 1);
}
.story__mark {
  font-family: var(--sc-font-text); font-style: italic;
  font-size: var(--sc-t-sm); color: var(--book-dark-soft);
  margin: 0 0 var(--sc-2);
}
.story__title {
  font-weight: 500;
  /* Height-aware, not just --sc-t-2xl: on a short viewport (a laptop at
     100% browser zoom is routinely under 800px of actual page height once
     chrome is subtracted) the fixed clamp left no room for six accumulated
     paragraphs below it inside the fixed 100vh stage, and the tail of the
     story silently clipped. The vh term shrinks this ahead of the text. */
  font-size: clamp(1.5rem, 1.1rem + 2.2vh, var(--sc-t-2xl));
  line-height: var(--sc-leading-tight); margin: 0 0 var(--sc-4);
}
.story__text p {
  /* Same height-aware reasoning as .story__title above: six paragraphs are
     visible at once by design (the accumulate-and-hold peak), so their
     combined height, not any one line, is what has to fit inside one fixed
     viewport regardless of window height or browser zoom. */
  font-size: clamp(0.95rem, 0.8rem + 1vh, var(--sc-t-lg));
  line-height: 1.5;
  color: var(--book-dark-ink); max-width: 32ch;
  margin: 0;
}
.story__text p + p { margin-top: clamp(var(--sc-3), 1.6vh, var(--sc-5)); }

/* The signature move: the blank the story prints itself around. Empty until
   the title-page input carries a name, then set live in accent ink by
   book.js — the same word, everywhere it belongs, at once. */
/* Default styling assumes the light paper ground, since that is most of the
   page; .ch--story below overrides both to the dark-ground accent tint. */
.name-slot { display: inline-block; font-style: normal; color: var(--sc-accent); font-weight: 600; }
.name-slot__rule {
  display: inline-block; width: 6.5ch; height: 1px;
  background: color-mix(in oklab, var(--sc-ink) 30%, transparent);
  transform: translateY(-0.35em);
}
.name-slot__value { display: none; }
.name-slot[data-filled] .name-slot__rule { display: none; }
.name-slot[data-filled] .name-slot__value { display: inline; }
.ch--story .name-slot { color: var(--book-dark-accent); }
.ch--story .name-slot__rule { background: color-mix(in oklab, var(--book-dark-ink) 45%, transparent); }

/* ================================================================ III · FLOW
   Shares .spread with Chapter I; only the reveal figure differs. */
.ch--method .plate__frame { clip-path: inset(0 0 0 0); will-change: clip-path; }
.ch--method .plate__frame[style*="clip-path"] { box-shadow: var(--sc-e2); }

/* =================================================================== PRICE
   The administrative beat. Compressed: a flow section with no pinned act, no
   dwell, real numbers, museum-label plainness (uniqueness.md's gallery
   grammar rail-copy discipline applied to a table instead of a rail). */
.ch--price { padding: var(--sc-10) var(--sc-gutter); }
/* The page-turn wrapper, kept separate from .pricepage (which carries its own
   data-sc-in reveal) so the two mechanisms never fight over the same
   element's opacity/transform.

   46rem, not the 34rem it used to be, and left-aligned rather than centred:
   this is the same measure .spread__text uses, so "Trečias skyrius" now opens
   at exactly the same x as "Pirmas skyrius" and "Antras skyrius". Any 46rem
   box centred in the viewport lands on that x, whatever wrapping gets it
   there, so the two constructions do not have to match — only the measure.
   The wider rotating box reaches further under rotateY, which .ch--price's
   own overflow:hidden clips (the turn is an inner wrapper for that reason). */
.price-turn { width: 100%; max-width: 46rem; margin-inline: auto; }
.pricepage { max-width: none; margin-inline: 0; }
.pricepage .chapter-title { margin-inline: 0; }

.tariff {
  margin: var(--sc-7) 0 0; border-collapse: collapse; width: 100%;
  max-width: 26rem; font-variant-numeric: tabular-nums;
}
.tariff tr + tr { border-top: 1px solid var(--sc-hairline); }
.tariff th, .tariff td { padding: var(--sc-3) var(--sc-2); font-weight: 400; }
.tariff th { text-align: left; color: var(--sc-ink-soft); }
.tariff td { text-align: right; font-family: var(--sc-font-display); font-style: italic; }

.tariff__note { margin: var(--sc-6) 0 0; max-width: 40ch; color: var(--sc-ink-soft); text-wrap: pretty; }
.tariff__example {
  margin: var(--sc-7) 0 0; font-family: var(--sc-font-display); font-style: italic;
  font-size: var(--sc-t-lg); color: var(--sc-ink);
}
/* ============================================================= V · IMPRINT
   The close. Pinned so the last screen holds. Resolves: smallest type on the
   site, the ask set as a line of running text rather than a button island. */
.ch--imprint { background: var(--sc-canvas); }
.stage.imprint { display: grid; place-items: center; }
.imprint__inner {
  width: 100%; max-width: 30rem; text-align: center;
  padding: var(--sc-8) var(--sc-gutter);
}
.imprint__mark { color: var(--sc-ink-soft); display: flex; justify-content: center; margin-bottom: var(--sc-6); }
.imprint__name { font-family: var(--sc-font-display); font-style: italic; font-size: var(--sc-t-lg); margin: 0; }
.imprint__blurb { color: var(--sc-ink-soft); max-width: 32ch; margin: var(--sc-3) auto var(--sc-7); text-wrap: pretty; }

.ask { margin: 0; }
.ask__line {
  font-size: var(--sc-t-base); line-height: 2.2; color: var(--sc-ink);
  display: inline;
}
.ask .blank { margin: 0 var(--sc-1); }
.ask input[type="email"] {
  font: inherit; color: var(--sc-ink); background: transparent; border: 0;
  border-bottom: 1px solid var(--sc-hairline-strong);
  padding: 0 var(--sc-1) 2px; width: 15ch; text-align: center;
  transition: border-color var(--sc-d-base) var(--sc-ease-out);
}
.ask input[type="email"]:hover { border-color: var(--sc-ink-soft); }
.ask input[type="email"]:focus-visible {
  outline: 2px solid var(--sc-accent); outline-offset: 3px;
  border-radius: var(--sc-r-sm); border-color: transparent;
}
.ask__go {
  font: inherit; font-family: var(--sc-font-text); font-weight: 600;
  font-size: var(--sc-t-sm); letter-spacing: var(--sc-track-wide); text-transform: uppercase;
  color: var(--sc-accent-ink); background: var(--sc-accent);
  border: 0; border-radius: var(--sc-r-pill);
  padding: 0.55em 1.3em; margin-left: var(--sc-2);
  cursor: pointer;
  box-shadow: var(--sc-e1);
  transition: transform 140ms var(--sc-ease-out), box-shadow 140ms var(--sc-ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .ask__go:hover { box-shadow: var(--sc-e2); }
}
.ask__go:active { transform: scale(0.97); }
.ask__go:focus-visible { outline: 2px solid var(--sc-ink); outline-offset: 3px; }

.imprint__links { margin-top: var(--sc-8); display: flex; gap: var(--sc-6); justify-content: center; }
.imprint__links a {
  color: var(--sc-ink-soft); text-decoration: none;
  font-size: var(--sc-t-sm); letter-spacing: var(--sc-track-wide); text-transform: uppercase;
  border-bottom: 1px solid transparent;
  transition: color 140ms var(--sc-ease-out), border-color 140ms var(--sc-ease-out);
}
.imprint__links a:hover { color: var(--sc-ink); border-color: var(--sc-hairline-strong); }
.imprint__links a:focus-visible { outline: 2px solid var(--sc-accent); outline-offset: 3px; border-radius: var(--sc-r-sm); }

.imprint__rule { height: 1px; background: var(--sc-hairline); margin: var(--sc-8) auto var(--sc-5); width: 4rem; }
.colophon { font-size: var(--sc-t-xs); color: var(--sc-ink-soft); letter-spacing: var(--sc-track-wide); margin: 0; }

/* ---------------------------------------------------------------- states -- */
.book input:disabled { opacity: 0.6; cursor: not-allowed; }

/* ------------------------------------------------------------- page turn --
   The bespoke section-to-section transition: each chapter's content turns
   into view like a page opening, hinged on its own left edge. One shot, via
   IntersectionObserver in book.js — not continuous scroll-scrubbing, which
   would need to be re-derived per element geometry and is far easier to get
   subtly wrong. Applied to a wrapper INSIDE each chapter (never to a
   position:sticky element itself, and never to an element that already
   carries data-sc-in/[data-sc-cue] — see book.js for exactly which). */
[data-page-turn] {
  transform-origin: left center;
  transform: perspective(2200px) rotateY(-9deg);
  opacity: 0;
  transition: transform 760ms var(--sc-ease-drawer), opacity 620ms var(--sc-ease-out);
  will-change: transform, opacity;
}
[data-page-turn].is-turned {
  transform: perspective(2200px) rotateY(0deg);
  opacity: 1;
}
@media (prefers-reduced-motion: reduce) {
  [data-page-turn] { transform: none; opacity: 1; transition: none; }
}

/* =============================================================== DASHBOARD
   A settings page, not a chapter of the book: one continuous document, no
   act/pin/page-turn devices. Same ground, ink and type as the rest of the
   book, but the grammar is "form the reader returns to and edits repeatedly",
   so nothing here is scroll-driven or one-shot. New form-control and card
   patterns live here because nothing on the narrative pages needed a
   labelled, multi-field form before now — .blank/.ask are for a single
   inline word, not a settings form. */
.dash { max-width: 48rem; margin-inline: auto; padding: var(--sc-9) var(--sc-gutter) var(--sc-10); }

.dash__head { text-align: center; margin-bottom: var(--sc-9); }
.dash__mark {
  color: var(--sc-ink-soft); display: flex; justify-content: center;
  margin-bottom: var(--sc-5);
  transition: color var(--sc-d-base) var(--sc-ease-out);
}
.dash__mark:hover { color: var(--sc-accent); }
.dash__mark:focus-visible { outline: 2px solid var(--sc-accent); outline-offset: 4px; border-radius: var(--sc-r-sm); }
.dash__eyebrow {
  font-family: var(--sc-font-display); font-style: italic;
  font-size: var(--sc-t-lg); color: var(--sc-ink-soft); margin: 0;
}
.dash__title {
  font-weight: 500;
  /* Same fix as .notice__title above: --sc-t-3xl is a hero-scale clamp
     that assumes its container grows with the viewport. .dash is a fixed,
     moderate-width settings column, so on a wide screen the old token
     pushed a title like "Pridėkite savo vaiką (-us)" past the box width
     at a huge size, wrapping it into a multi-line stack of oversized
     words instead of one or two ordinary lines. */
  font-size: clamp(2rem, 1.6rem + 1.8vw, 2.9rem);
  line-height: var(--sc-leading-tight); margin: var(--sc-2) 0 var(--sc-3);
}
.dash__status { color: var(--sc-ink-soft); margin: 0; }
.dash__status strong { color: var(--sc-ink); font-weight: 600; }

.dash__section { margin-top: var(--sc-10); padding-top: var(--sc-8); border-top: 1px solid var(--sc-hairline); }
.dash__section:first-of-type { margin-top: var(--sc-9); }
.dash__section > h2 {
  font-family: var(--sc-font-display); font-weight: 500;
  font-size: var(--sc-t-2xl); line-height: var(--sc-leading-tight);
  margin: 0 0 var(--sc-6);
}
.dash__section-head { margin-bottom: var(--sc-6); }
.dash__section-head > h2 { margin: 0; }
.dash__note { color: var(--sc-ink-soft); max-width: 48ch; text-wrap: pretty; }
.dash__error {
  color: var(--sc-accent); background: color-mix(in oklab, var(--sc-accent) 10%, transparent);
  border: 1px solid color-mix(in oklab, var(--sc-accent) 30%, transparent);
  border-radius: var(--sc-r-sm); padding: var(--sc-4) var(--sc-5);
  margin: var(--sc-7) 0 0;
}

/* Onboarding's plain roll call of already-added children, ahead of the
   payment step: a list, not .entry cards — those are for records you can
   edit right there, and these are just a confirmation of what was typed
   into the form below. */
.dash__childlist { list-style: none; margin: 0; padding: 0; }
.dash__childlist li {
  padding: var(--sc-3) 0; border-bottom: 1px solid var(--sc-hairline);
}
.dash__childlist li:first-child { padding-top: 0; }
.dash__childlist-age { color: var(--sc-ink-soft); font-size: var(--sc-t-sm); }

.dash__entries { display: flex; flex-direction: column; gap: var(--sc-7); }

/* One child's record. A hairline frame, not a shadowed marketing card: the
   content here is real and specific to this one child, not an identical
   feature tile (taste.md's card ban is about the latter). */
.entry {
  border: 1px solid var(--sc-hairline); border-radius: var(--sc-r-md);
  padding: var(--sc-7); background: var(--sc-surface);
}
.entry--add { border-style: dashed; border-color: var(--sc-hairline-strong); background: transparent; }
.entry > h3 {
  font-family: var(--sc-font-display); font-style: italic; font-weight: 500;
  font-size: var(--sc-t-lg); margin: 0 0 var(--sc-6);
}
.entry__actions { margin-top: var(--sc-6); }
.entry__remove { margin-top: var(--sc-4); }

.field-grid {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--sc-5);
}
.field { margin-top: var(--sc-5); }
.field-grid .field { margin-top: 0; }
.field:first-child { margin-top: 0; }
.field label {
  display: block; margin-bottom: var(--sc-2);
  font-size: var(--sc-t-xs); letter-spacing: var(--sc-track-wide); text-transform: uppercase;
  color: var(--sc-ink-soft);
}
.field input[type="text"], .field input[type="number"], .field select, .field textarea {
  width: 100%; font: inherit; font-size: var(--sc-t-base); color: var(--sc-ink);
  background: var(--sc-canvas); border: 1px solid var(--sc-hairline-strong);
  border-radius: var(--sc-r-sm); padding: var(--sc-3) var(--sc-4);
  transition: border-color var(--sc-d-base) var(--sc-ease-out), box-shadow var(--sc-d-base) var(--sc-ease-out);
}
.field textarea { min-height: 5rem; resize: vertical; font-family: var(--sc-font-text); }
.field input:hover, .field select:hover, .field textarea:hover { border-color: var(--sc-ink-soft); }
.field input:focus-visible, .field select:focus-visible, .field textarea:focus-visible {
  outline: none; border-color: var(--sc-accent);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--sc-accent) 22%, transparent);
}

/* Buttons: one accent (taste.md), so danger is signalled by placement and
   an outline treatment, not a second hue. */
.btn {
  font: inherit; font-family: var(--sc-font-text); font-weight: 600;
  font-size: var(--sc-t-sm); letter-spacing: var(--sc-track-wide); text-transform: uppercase;
  border-radius: var(--sc-r-pill); padding: 0.7em 1.5em; cursor: pointer;
  transition: transform 140ms var(--sc-ease-out), box-shadow 140ms var(--sc-ease-out),
              border-color 140ms var(--sc-ease-out), color 140ms var(--sc-ease-out);
}
.btn:disabled { opacity: 0.6; cursor: not-allowed; }
.btn--primary {
  color: var(--sc-accent-ink); background: var(--sc-accent); border: 1px solid transparent;
  box-shadow: var(--sc-e1);
}
.btn--ghost { color: var(--sc-ink-soft); background: transparent; border: 1px solid var(--sc-hairline-strong); }
.btn--danger { color: var(--sc-accent); background: transparent; border: 1px solid var(--sc-accent); }
@media (hover: hover) and (pointer: fine) {
  .btn--primary:hover { box-shadow: var(--sc-e2); }
  .btn--ghost:hover { color: var(--sc-ink); border-color: var(--sc-ink); }
  .btn--danger:hover { color: var(--sc-accent-ink); background: var(--sc-accent); }
}
.btn:active { transform: scale(0.97); }
.btn:focus-visible { outline: 2px solid var(--sc-accent); outline-offset: 3px; }

.dash__section--danger > h2 { color: var(--sc-accent); }
.dash__section--danger .dash__note { margin-bottom: var(--sc-5); }

.dash__logout { text-align: center; margin-top: var(--sc-9); }
.dash__logout a {
  color: var(--sc-ink-soft); font-size: var(--sc-t-sm);
  letter-spacing: var(--sc-track-wide); text-transform: uppercase;
  text-decoration: none; border-bottom: 1px solid transparent;
  transition: color 140ms var(--sc-ease-out), border-color 140ms var(--sc-ease-out);
}
.dash__logout a:hover { color: var(--sc-ink); border-color: var(--sc-hairline-strong); }
.dash__logout a:focus-visible { outline: 2px solid var(--sc-accent); outline-offset: 3px; border-radius: var(--sc-r-sm); }

/* --------------------------------------------------------- reduced motion -- */
@media (prefers-reduced-motion: reduce) {
  .story__col { opacity: 1; }
}

/* --------------------------------------------------------------- mobile -- */
@media (max-width: 860px) {
  /* Asymmetric here too, for the same reason as the desktop rule. */
  .spread { gap: var(--sc-6); padding-block: var(--sc-8) var(--sc-6); }
  .plate--wide .plate__frame { height: min(50vh, 420px); }
  /* The hero carries its own narrow-viewport branch (it is written
     mobile-first, with min-width branches for the two-column overlay), so
     the opening needs no override here. */
  .story__col { max-width: none; padding: var(--sc-8) var(--sc-gutter); }
  .story__text p { max-width: none; font-size: var(--sc-t-base); }
  /* Measured against the real render, not eyeballed: with six accumulated
     paragraphs (the story chapter's own peak device) the text column
     regularly reaches 60-70% of viewport height on a phone, and the
     original stops (transparent by 72%) left the last one or two lines
     sitting directly on the plate's brightest, warmest ground — measured at
     3.71:1 against the text colour, below the 4.5:1 body-text floor. These
     stops keep every paragraph's position comfortably covered and only let
     the plate breathe in the final sliver where text never reaches. */
  .story__veil {
    background: linear-gradient(180deg,
      color-mix(in oklab, var(--book-dark-canvas) 88%, transparent) 0%,
      color-mix(in oklab, var(--book-dark-canvas) 80%, transparent) 45%,
      color-mix(in oklab, var(--book-dark-canvas) 62%, transparent) 68%,
      color-mix(in oklab, var(--book-dark-canvas) 40%, transparent) 85%,
      color-mix(in oklab, var(--book-dark-canvas) 22%, transparent) 100%);
  }
  .folio { display: none; }
  .ask__line { line-height: 2.6; }
  .field-grid { grid-template-columns: 1fr; }
  .entry { padding: var(--sc-6) var(--sc-5); }
}
