/* ==========================================================================
   ivanished.art — Coming Soon

   LAYOUT SYSTEM SOURCE OF TRUTH (read before editing anything below):
   C:\Users\iform\Local Sites\ivanished\app\public\wp-content\themes\ivanished\style.css
   — the real hand-coded WordPress theme, running in the Local by WP Engine
   environment (NOT the stock Docker WordPress that lives in this repo).
   Every "theme §N / theme line NNN" reference in the comments below points
   into that file. This page was originally built without consulting it and
   improvised its own spacing system; this round replaces that improvised
   system with the real one, mechanism for mechanism.

   What is unchanged: the colour, font, radius and spacing tokens below.
   They already mapped 1:1 to DESIGN.md and to the theme's own :root block.

   What was ported this round:
     · --rule-step (22px) — the single baseline-grid unit
     · the ruled-line background derived from it (theme line ~500)
     · the font-metric-derived heading formula (theme §1/§2, lines 183-302)
     · the 1100px container + left-aligned copy (theme §3 line 417, §11)
     · .margin-rule, the vertical red-pink notepad line (theme lines 172-181)
   ========================================================================== */

:root {
  /* --- Colors — Base (the page) ---------------------------------------- */
  --color-paper: #FBF8F1;
  --color-paper-line: #CFE0EE;
  --color-paper-margin: #E8A9A0;
  --color-paper-shadow: rgba(39, 39, 39, 0.15);

  /* --- Colors — Ink (the pen) -------------------------------------------*/
  --color-ink: #272727;
  --color-caption-red: #D8313A;
  --color-subhead-blue: #1C4875;

  /* --- Colors — Sticky notes ---------------------------------------------*/
  --color-sticky-yellow: #FFE299; /* locked default CTA */
  --color-sticky-red: #FFB8A8;
  --color-sticky-blue: #A8DAFF;
  --color-sticky-green: #B3EFBD;
  --color-sticky-teal: #B3F4EF;
  --color-sticky-orange: #FFD3A8;

  /* --- Colors — Highlighter ----------------------------------------------*/
  --color-highlighter-red: #E41100;
  --color-highlighter-blue: #CEECF6;
  --color-highlighter-green: #D0E3CF;

  /* --- Colors — On-color text / semantic ---------------------------------*/
  --color-on-sticky: var(--color-ink);
  --color-on-dark: #FBF8F1;
  --color-success: #3A8355;
  --color-warning: #A4680B;
  --color-error: #C4342B;

  /* --- Type — families ----------------------------------------------------*/
  --font-display: 'Kalam', cursive;   /* hero / section titles only */
  --font-hand: 'Caveat', cursive;     /* accents, sticky notes, margin notes */
  --font-body: 'Nunito', sans-serif;  /* body, nav, buttons, labels */

  /* --- Type — sizes ------------------------------------------------------
     Fixed values, not fluid clamp()s. The theme deliberately steps type
     down at fixed breakpoints instead of scaling it fluidly, because each
     size is paired with a row count N in the heading formula below — a
     continuously-changing font-size has no stable N and would slide the
     baseline off the rule lines between breakpoints. See §5 (Responsive)
     for the step-downs, which mirror theme lines 1746 and 1788. */
  --text-display-hero: 56px;
  --text-display-section: 34px;
  --text-title: 20px;
  --text-hand-note: 26px;
  --text-hand-caption: 19px;
  --text-body: 16px;
  --text-body-sm: 14px;
  --text-button: 15px;

  /* --- Baseline grid — ported from the theme's :root (theme §0) ----------

     --rule-step is the one unit this whole page is built on: the vertical
     spacing of the horizontal notebook lines AND the literal line-height
     of every grid-bound text level (each level being a whole multiple of
     it). It is not an eyeballed number — the theme derives it from
     Nunito's own hhea metrics (ascent 1011 + descent 353 per 1000
     units/em ≈ 1.36em), so 22px at the 16px body size is effectively
     Nunito's own native vertical box rounded to a clean px value, with no
     synthetic "comfortable" slack layered on top. Body copy = 1 row is
     the snug anchor the value is calibrated for. Full derivation and the
     three retired earlier approaches: theme style.css lines 55-83.

     The rule this page now obeys everywhere: every box in the vertical
     chain from the top of the document down (container padding,
     illustration height, heading footprints, paragraph line-height and
     margins, section padding) is a whole multiple of --rule-step, so
     text lands on the lines instead of drifting between them. */
  --rule-step: 22px;

  /* 5% of a row (~1.1px) of breathing room. The baseline-anchored heading
     formula below originally landed a heading's baseline EXACTLY on its
     target rule line, which reads as text sitting right on top of the
     line with zero gap. This gap is subtracted from padding-top (so the
     baseline sits that far above its target line) and added back into
     margin-bottom, so the row-invariant total footprint still holds
     exactly. Theme lines 86-95. */
  --heading-gap: calc(var(--rule-step) * 0.05);

  /* Vertical margin rule — theme lines 104-107. --content-inset IS now
     ported (theme line 107: margin-line-x + margin-line-w + --space-xs =
     68 + 2 + 8 = 78px) — corrected from an earlier pass that reasoned
     this page has no full-bleed element and could skip it. That reasoning
     missed that .page itself becomes the full-bleed-equivalent element
     below ~1100px: below that width, its max-width:1100px box no longer
     gets any extra auto-centering margin on top of its own padding, so
     .page's actual left edge sits at exactly padding-left from the
     viewport edge — inside the margin-rule's 68-70px zone once
     padding-left drops to --space-lg (24px), letting body copy start
     left of (and run through) the rule. See .page's own padding-left
     below. */
  --margin-line-x: 68px;
  --margin-line-w: 2px;
  --content-inset: 78px;

  /* --- Radii ----------------------------------------------------------- */
  --radius-sticker: 10px;
  --radius-note: 4px;
  --radius-sticky: 6px;
  --radius-bubble: 20px;
  --radius-pill: 9999px;

  /* --- Spacing ----------------------------------------------------------
     Horizontal spacing and the internal spacing of opaque components
     (buttons, inputs) stays on this scale, exactly as in the theme —
     --rule-step governs the VERTICAL rhythm only. */
  --space-xxs: 4px;
  --space-xs: 8px;
  --space-sm: 12px;
  --space-md: 16px;
  --space-lg: 24px;
  --space-xl: 32px;
  --space-xxl: 48px;
  --space-section: 72px;
}

/* ==========================================================================
   1. Reset / base — theme §1
   ========================================================================== */

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

html {
  -webkit-text-size-adjust: 100%;

  /* The paper colour is set HERE as well as on body, deliberately. An
     <html> with no background of its own makes the browser propagate
     body's background up to the canvas, which also moves that
     background's positioning area onto the root box. Giving html the flat
     paper colour stops the propagation, so body's ruled-line gradient
     below paints in body's OWN padding box — origin exactly y = 0 of the
     document, which is the zero every --rule-step multiple on this page
     is measured from. */
  background-color: var(--color-paper);
}

body {
  margin: 0;
  min-height: 100vh;

  /* position: relative makes body the containing block for .margin-rule,
     so that element's top:0/bottom:0 spans body's full rendered height
     (the whole document) rather than just the viewport — theme lines
     137-140. */
  position: relative;

  color: var(--color-ink);
  background-color: var(--color-paper);
  font-family: var(--font-body);
  font-size: var(--text-body);

  /* Fallback only — this no longer sets the running-copy rhythm. That is
     the `p` rule's job below (line-height: var(--rule-step), the "body =
     1 row" anchor). 1.5 stays correct for the compact UI elements that
     are out of the baseline grid by design — buttons, inputs, the
     footer line — which paint their own opaque box or carry no rule line
     underneath. Theme lines 151-161. */
  line-height: 1.5;

  /* Ruled paper — the theme's exact pattern (theme line ~500) at exactly
     --rule-step: a 1px line at the TOP of every 22px row.

     One page-length gradient, not the theme's per-section ::before
     breakout. That mechanism exists in the theme because it stacks many
     sections whose rendered heights are content-dependent (product
     images, variable-height sticky-note tiles), so each section has to be
     able to restart the grid at its own top. This page is a single
     continuous column on a single sheet of paper: re-originating the
     pattern partway down would only introduce a visible seam — a band
     that isn't 22px tall — where a real notepad has none. Instead every
     box in this page's vertical chain is a rule-step multiple (see
     §3/§4), so one origin at the top of the document is enough. */
  background-image: repeating-linear-gradient(
    to bottom,
    var(--color-paper-line) 0,
    var(--color-paper-line) 1px,
    transparent 1px,
    transparent var(--rule-step)
  );
}

/* The red-pink "this is a real notepad" page-margin tell — a real element
   rather than a body background-image (the mechanism this page used
   before, and the one the theme itself retired), so it paints above
   anything with its own opaque background and runs uninterrupted from the
   very top of the page to the very bottom. pointer-events: none keeps it
   from ever intercepting a click. Theme lines 164-181. Hidden below 600px
   in §5, same as the theme (theme lines 1759-1769). */
.margin-rule {
  position: absolute;
  top: 0;
  bottom: 0;
  left: var(--margin-line-x);
  width: var(--margin-line-w);
  background: var(--color-paper-margin);
  z-index: 20;
  pointer-events: none;
}

h1, h2, h3, h4, h5, h6 {
  margin: 0 0 var(--rule-step); /* 1 row below any heading — overridden per level in §2 by the descent-based value the formula requires */
  color: var(--color-ink);
  font-weight: 500;
}

/* Running copy — the theme's confirmed "body = 1 row" anchor, and the
   anchor --rule-step itself is calibrated for. line-height forces every
   wrapped line of a paragraph onto its own 22px row; the matching
   margin-bottom skips one clean row between paragraphs, so a paragraph of
   ANY number of lines still occupies a whole number of rows and nothing
   below it drifts. Theme line 311. */
p {
  margin: 0 0 var(--rule-step);
  line-height: var(--rule-step);
}

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

button, input, select, textarea { font-family: var(--font-body); }

::selection { background: var(--color-sticky-yellow); color: var(--color-ink); }

/* ==========================================================================
   2. Type levels — the baseline-anchored heading formula (theme §1/§2)

   The mechanism, in three parts per level (full reasoning at theme lines
   183-302 — worth reading there rather than re-deriving here):

     1. line-height is UNITLESS and tight, set to the font's own natural
        single-line box (hhea ascent + descent, no synthetic leading), so
        a wrapped heading's own line spacing is honest to the font.
        Kalam:  ascent 1.063 + descent 0.531 = 1.594
        Caveat: ascent 0.960 + descent 0.300 = 1.26
        Nunito: ascent 1.011 + descent 0.353 = 1.364
     2. padding-top = N × --rule-step − <ascent>em − --heading-gap, which
        lands the first line's baseline --heading-gap above the N-th rule
        line. Expressed in em, so it auto-recomputes off whatever
        font-size the level resolves to (see the responsive steps in §5 —
        only padding-top ever needs redeclaring there, because only N
        changes).
     3. margin-bottom = M × --rule-step − <descent>em + --heading-gap,
        i.e. the font's own descender clearance plus the gap padding-top
        gave up, with the remainder made up in margin — so the total
        footprint is algebraically always (N + M) × --rule-step:
          (N·step − asc − gap) + (asc + desc) + (M·step − desc + gap)
          = (N + M) · step
        …regardless of font-size or metrics. M is 1 row everywhere except
        the 56px hero, where Kalam's descent alone (0.531 × 56 = 29.7px)
        already exceeds a single 22px row and M must be 2 (theme lines
        347-355).
   ========================================================================== */

/* .hero — this page's one h1, at the theme's .display-hero tier
   (theme lines 369-377; the theme's own home-page hero heading uses the
   identical formula at lines 1309-1318).
   56px Kalam → N = 5 leading rows (56 × 1.594 = 89.3px needs 110px/5 rows
   to clear, 20.7px headroom) + M = 2 trailing rows. Total footprint
   exactly 7 rows = 154px.
   This replaces an improvised clamp(2.1rem, 5vw + 1.2rem, 56px), which
   had no relationship to the row math at any viewport width. */
.hero {
  font-family: var(--font-display);
  font-size: var(--text-display-hero); /* 56px */
  font-weight: 700; /* Kalam has no 500; 700 is the closest loaded weight */
  line-height: 1.594;
  letter-spacing: 0;
  padding-top: calc(var(--rule-step) * 5 - 1.063em - var(--heading-gap));
  margin-bottom: calc(var(--rule-step) * 2 - 0.531em + var(--heading-gap));
}

/* Body copy. Reading measure capped at the theme's own 680px column
   (theme lines 1391-1410, .page-upcoming-projects .intro /
   .page-about .brand-story) — the container is 1100px wide, but running
   copy set the full width of it would be a ~130-character line. Line
   count is irrelevant to the grid here: at line-height = 1 row and
   margin-bottom = 1 row, any number of lines still occupies whole rows. */
.description {
  font-family: var(--font-body);
  font-size: var(--text-body);
  font-weight: 400;
  max-width: 680px;
  margin-left: auto;
  margin-right: auto;
}

/* .hand-caption — theme lines 402-410, unchanged tier (19px Caveat,
   caption red). N = 2, M = 1 → 3 rows total. */
.hand-caption {
  font-family: var(--font-hand);
  font-size: var(--text-hand-caption); /* 19px */
  font-weight: 600;
  line-height: 1.26;
  padding-top: calc(var(--rule-step) * 2 - 0.96em - var(--heading-gap));
  margin-bottom: calc(var(--rule-step) - 0.3em + var(--heading-gap));
  color: var(--color-caption-red);
}

/* .capture-title — 20px Nunito bold is the theme's .title-text tier
   (theme lines 386-393), so it takes that tier's formula: N = 1 (the
   tightest level in the system — the ascent alone is 20.2px of a 22px
   row), M = 1 → 2 rows total. It stays Nunito rather than becoming the
   theme's Kalam h2, because the tier is chosen by size/role, not by tag. */
.capture-title {
  font-family: var(--font-body);
  font-size: var(--text-title); /* 20px */
  font-weight: 700;
  line-height: 1.364;
  padding-top: calc(var(--rule-step) - 1.011em - var(--heading-gap));
  margin-bottom: calc(var(--rule-step) - 0.353em + var(--heading-gap));
}

/* ==========================================================================
   3. Layout shell — theme §3 (.site-content, line 417) and §11 (.hero)

   The page was previously a ~640px centred card with text-align: center
   on everything, then briefly a 1100px container with copy left-aligned
   to match the theme (theme .hero__copy line 1280, .story-teaser line
   1330). Ivan reviewed the left-aligned version and asked for the whole
   page centred instead — a deliberate, explicit deviation from the
   theme's left-aligned pattern for this one-off coming-soon page, not a
   reversion to the old card layout: the 1100px container and the
   --content-inset margin-rule floor stay exactly as the theme defines
   them, only text-align (and the centering of block-level children that
   don't respond to text-align alone — see §4) changed. The footer
   shares the same container so it lines up with the copy above it and
   clears the margin rule the same way.
   ========================================================================== */

.page,
.footer {
  max-width: 1100px;
  margin-left: auto;
  margin-right: auto;
  padding-right: var(--space-lg);
}

.footer {
  padding-left: max(var(--space-lg), var(--content-inset));
}

.page {
  /* Left padding must never resolve below --content-inset (78px), the
     same floor the real theme applies to its full-bleed .site-header /
     .site-footer (theme lines 1087-1099, padding-left only — this is
     deliberately asymmetric, since only the left edge has a rule to
     clear). Below ~1100px viewport width .page IS that page's
     full-bleed-equivalent element (see the --content-inset comment in
     :root above), so it needs the same floor. max() means the plain
     --space-lg value keeps governing once the box is wide enough that its
     own auto-centering margin already clears the rule on its own.
     1 row of entry breathing room at the top, matching the theme's first
     section (theme lines 517-520); 2 rows at the bottom, matching its
     inter-section padding (line 514). Both are rule-step multiples, which
     is what puts the first element of the page on a rule line to begin
     with. */
  padding-left: max(var(--space-lg), var(--content-inset));
  padding-top: var(--rule-step);
  padding-bottom: calc(var(--rule-step) * 2);
  text-align: center;
}

/* hero-illustration — the "Weird Takes presents: / Coming soon" artwork.
   Its frame is baked into the PNG, so no CSS border/shadow is added.

   HEIGHT, not width, is what the baseline grid cares about: an image of
   arbitrary rendered height pushes every line of copy below it off the
   rule lines, which is the one case the theme solves with a per-section
   grid restart (theme lines 423-437). Here it can be solved outright,
   because this image's aspect ratio is known and fixed: 18 rows = 396px,
   and since the source PNG is exactly 16:9 (1920 × 1080) that resolves to
   exactly 704px wide under width: auto — no crop, no distortion, and the
   headline underneath starts on a rule line.

   object-fit is the guard for viewports narrower than the natural width:
   the box keeps its whole-row height and the artwork scales down inside
   it rather than being squashed by max-width.

   No margin-bottom: the h1 below carries 49px of its own leading in
   padding-top (see §2), which is the gap. */
.hero-illustration {
  height: calc(var(--rule-step) * 18);
  width: auto;
  max-width: 100%;
  object-fit: contain;
  object-position: left top;
  margin: 0 auto;
}

/* ==========================================================================
   4. Components (per DESIGN.md "Component Treatment Notes")

   Opaque components — the sticker button and the text input — are out of
   the baseline grid INTERNALLY by design, not omission (theme §4/§8):
   each paints its own background over the ruled paper, so there is no
   rule line inside their box to align to. What still has to be a
   rule-step multiple is their OUTER height, since the copy below them
   inherits their position — hence the explicit 2-row control height in
   .capture-form.
   ========================================================================== */

/* highlighter-mark — translucent marker stroke behind a key phrase.
   Currently unused in this page's markup; left as authored. */
mark.highlighter {
  background: linear-gradient(to bottom, transparent 38%, var(--color-highlighter-blue) 38%, var(--color-highlighter-blue) 88%, transparent 88%);
  color: inherit;
  padding: 0 2px;
  border-radius: 2px;
}

/* email capture block. 2 rows of separation above it — the theme's
   section-level break (theme line 514), not a paragraph-level gap. */
.capture {
  padding-top: calc(var(--rule-step) * 2);
  max-width: 480px;
  margin-left: auto;
  margin-right: auto;
}

.capture-form {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--rule-step); /* stacked: 2 rows + 1 row gap + 2 rows = 5 whole rows */
}

/* Both controls are pinned to exactly 2 rows so the form's own height is
   a rule-step multiple in either direction and .capture-note below it
   still lands on a line. 44px is also a correct touch-target height. */
.capture-form .text-input,
.capture-form .button-sticker {
  height: calc(var(--rule-step) * 2);
}

@media (min-width: 480px) {
  .capture-form {
    flex-direction: row;
    align-items: stretch;
    justify-content: center;
    gap: var(--space-sm); /* horizontal gap — the --space-* scale still governs horizontal spacing */
  }
}

/* text-input — ruled-paper feel, ink-colored border (theme §8) */
.text-input {
  flex: 1 1 auto;
  background-color: var(--color-paper);
  color: var(--color-ink);
  font-family: var(--font-body);
  font-size: var(--text-body);
  border: 1.5px solid var(--color-ink);
  border-radius: var(--radius-note);
  padding: 10px 14px;
  min-width: 0;
}

.text-input:focus {
  outline: 2px solid var(--color-subhead-blue);
  outline-offset: 1px;
}

/* button-sticker — the primary CTA, a die-cut sticker lifted off the page.
   Shadow and hover ported from the theme (lines 547-575): a hard offset
   shadow with no blur is what reads as a sticker sitting on paper; the
   soft blurred drop-shadow this page had instead is a generic web
   treatment and was one of the tells that it wasn't built with the system. */
.button-sticker {
  display: inline-block;
  background-color: var(--color-sticky-yellow);
  color: var(--color-ink);
  font-family: var(--font-body);
  font-weight: 700;
  font-size: var(--text-button);
  line-height: 1;
  border: none;
  border-radius: var(--radius-sticker);
  padding: 12px 22px;
  box-shadow: 3px 5px 0 var(--color-paper-shadow);
  transform: rotate(-1deg);
  cursor: pointer;
  transition: transform 200ms ease, box-shadow 200ms ease;
  text-align: center;
  white-space: nowrap;
}

.button-sticker:hover,
.button-sticker:focus-visible {
  transform: rotate(0deg) translateY(-2px);
  box-shadow: 4px 10px 16px -4px var(--color-paper-shadow);
}

/* 1 row of separation above the note; the `p` rule supplies the rest. */
.capture-note {
  font-family: var(--font-body);
  font-size: var(--text-body-sm);
  color: var(--color-ink);
  opacity: 0.7;
  margin-top: var(--rule-step);
}

/* honeypot field — hidden from real visitors, catches basic bots */
.hp-field {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* screen-reader-only text — visually hidden, still announced */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.footer {
  margin-top: calc(var(--rule-step) * 2);
  padding-bottom: calc(var(--rule-step) * 2);
  font-family: var(--font-body);
  font-size: var(--text-body-sm);
  line-height: var(--rule-step);
  color: var(--color-ink);
  opacity: 0.6;
  text-align: center;
}

/* ==========================================================================
   5. Responsive — fixed steps, not fluid scaling (theme §15)

   The theme steps the hero heading down at fixed breakpoints because each
   font-size is paired with its own row count N; line-height and
   margin-bottom are deliberately NOT redeclared, since both are already
   unitless/em and depend only on font-size — they recompute correctly by
   falling through from the base rule. Only padding-top carries an
   override, because only it depends on N.
   ========================================================================== */

@media (max-width: 768px) {
  .page,
  .footer {
    padding-right: var(--space-md);
  }

  .footer {
    padding-left: max(var(--space-md), var(--content-inset));
  }

  /* Same --content-inset floor as the base rule above, re-applied against
     the narrower --space-md so it isn't lost at this breakpoint — the
     margin-rule is still visible down to 600px and this block covers part
     of that range (600-768px). */
  .page {
    padding-left: max(var(--space-md), var(--content-inset));
  }

  /* 42px Kalam needs N = 4, not 5: 42 × 1.594 = 67.0px, which no longer
     needs a 110px allotment — 88px/4 rows leaves 21.1px of headroom.
     Theme line 1746. */
  .hero {
    font-size: 42px;
    padding-top: calc(var(--rule-step) * 4 - 1.063em - var(--heading-gap));
  }

  /* 12 rows = 264px tall (≈469px wide at 16:9) — still a whole-row height,
     so the copy below stays on the lines at this width too. */
  .hero-illustration {
    height: calc(var(--rule-step) * 12);
  }
}

@media (max-width: 600px) {
  /* Drop the vertical margin rule at phone widths — a red rule that close
     to the edge reads as cramped rather than notebook-like. The
     horizontal ruled lines are untouched and keep the same --rule-step at
     every breakpoint. Theme lines 1759-1769. */
  .margin-rule {
    display: none;
  }

  /* 34px Kalam → N = 3 (66px allotment, 11.8px headroom). Theme line 1788. */
  .hero {
    font-size: 34px;
    padding-top: calc(var(--rule-step) * 3 - 1.063em - var(--heading-gap));
  }

  /* 9 rows = 198px tall, exactly 352px wide at 16:9. */
  .hero-illustration {
    height: calc(var(--rule-step) * 9);
  }
}
