/*
 * Generated by scripts/port-css.mjs from the CSS Modules that preceded
 * this theme. Edit the rules here — the generator is kept for reference,
 * not re-run against a moved target.
 */

/* ─── components/sections/Interlude.module.css ─────────────────────────────────────── */
/* ── The band ────────────────────────────────────────────────────────
   A coloured chapter break between two white product sections. `isolation`
   matters: `AuroraField`'s blobs composite with `mix-blend-mode: screen`, and
   without a stacking context of their own they would blend against whatever
   happens to be painted behind the section rather than against the band's own
   ground.

   Square corners, unlike `BundleBuilder.module.css`, which rounds its top edge
   where it goes lilac. A radius makes a coloured section read as a *card* laid
   on the page — an object among the product sections. This band is meant to be
   the page changing colour underneath you, and a hard edge is what sells the
   change of ground rather than the arrival of a panel. */
.us-il {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  padding-block: var(--air);
  padding-inline: var(--gutter);
  /* Ground colour under the sky, so a slow-painting gradient never leaves the
     band flashing plain white as it arrives. */
  background: var(--sky-base);
  margin-block: clamp(1.5rem, 4vh, 3.5rem);
  /*
   * Stop at the section rail rather than run under it.
   *
   * `SectionRail` is `position: fixed` and deliberately opaque white
   * (`SectionRail.module.css`) so section content can never show through its
   * labels. Every white section is invisible under it; a coloured one is not —
   * the band ran full width and the rail cut a bright slab down its right edge.
   *
   * This is also why the band does not use the global `.section` class: that
   * reserves the rail as *padding*, which keeps content clear of it but still
   * paints the background underneath. A coloured band needs it as margin.
   * Below 900px `--rail` is `0px` and this goes full bleed on its own.
   */
  margin-right: var(--rail);
}

/* Centred, unlike the left-ranged band this replaced: the headline now has
   art threaded through it and unicorns parked either side, and both of those
   are compositions around an axis. */
.us-il-inner {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  /* The band's whole job is to be a pause, and a pause set at the same
     1.5rem rhythm as a product section is not one — the eyebrow, the two
     headline lines and the lede arrived as a single dense slab. This opens
     with the viewport, so the air grows with the type rather than staying a
     fixed gap under a headline that has doubled in size. */
  gap: clamp(1.6rem, 3.4vw, 3rem);
  max-width: min(100%, 1000px);
  margin-inline: auto;
}

/*
 * A veil of white between the sky and the copy.
 *
 * The ground here is four pigment washes plus a few hundred motes of drifting
 * dust, and grey body text laid straight onto that had sparkles passing
 * through its counters — legible in a still, not while the field moves. The
 * veil lifts only the middle, so the band keeps its colour at the edges where
 * nothing has to be read.
 *
 * `z-index: -1` inside `.inner`'s own stacking context (`z-index: 1` above):
 * it paints over `AuroraField` at 0 and under every child here, including the
 * charms — which is why the unicorns read *cleaner* against it, not dimmer.
 */
.us-il-inner::before {
  content: '';
  position: absolute;
  inset: -16% -12%;
  z-index: -1;
  pointer-events: none;
  background: radial-gradient(
    closest-side,
    rgba(255, 255, 255, 0.78) 0%,
    rgba(255, 255, 255, 0.58) 46%,
    rgba(255, 255, 255, 0) 100%
  );
}

/* Deeper than the global `.eyebrow`'s `--grey`, which is a token picked for a
   white ground: on the sky it sat at about 2:1 and read as a smudge. */
/* Scoped under `.wrap` so it outranks the global `.eyebrow` whatever order the
   stylesheets load in. At equal specificity the production build loaded
   globals.css last and silently dropped this override (dev did not). */
.us-il .us-il-eyebrow { color: rgba(20, 16, 26, 0.7); }

/* ── The headline ────────────────────────────────────────────────────
   v1's hero layout, reused: see the note in `interludes.ts`. */
.us-il-head { position: relative; }

/*
 * The house display face, sized locally rather than borrowing `.display-md`.
 * That global tops out at 6vw / 5.2rem, which is wider than the authored line
 * breaks survive at this measure — and overriding one property of a global
 * class from a CSS module is a bet on stylesheet order, since both are a
 * single class and neither wins on specificity.
 *
 * Both ends of the ramp are set by things other than taste. The floor is low
 * because the tiles are sized in `em` off this and `.line` is `nowrap` by
 * design: at 360px the longest line is nineteen characters plus an image plus
 * two gaps, and it has to fit. The slope is what leaves the unicorns somewhere
 * to stand — the headline is about 13.7em wide, so a steeper ramp eats the
 * clear space either side of it before the band's own edge does, and the
 * charms end up clipped at the widths between 900px and about 1200px.
 *
 * Eased from 4.9vw to 4.6vw when the charms were pushed off the type. The
 * charms are pinned to the headline's own edges, so a shorter line does not
 * widen the gap by itself — what it widens is the margin between the pair and
 * the band's edge, and that margin is the budget `--charm-gap` spends. Below
 * about 1426px the ramp is what sets the size, and that whole range was the
 * squeeze; above it the 4.1rem cap is in charge and nothing here changes,
 * which is why this is the lever rather than the cap.
 */
.us-il-headline {
  display: flex;
  flex-direction: column;
  align-items: center;
  font-family: var(--font-display);
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: -0.03em;
  font-size: clamp(1.35rem, 4.6vw, 4.1rem);
  /* Tighter than the global: two stacked lines should read as one block —
     but not so tight that the tiles in one line crowd the caps of the next.
     0.94 had the reels almost touching, which is most of why the band read
     as cluttered. */
  line-height: 1.02;
  position: relative;
  z-index: 1;
}

/* One authored line. The break is deliberate rather than reflowed — a tile in
   a gap only works if the gap stays where it was placed — so the row never
   wraps and the words either side of a reel keep their pairing. */
.us-il-line {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.16em;
  flex-wrap: nowrap;
}

.us-il-word { position: relative; display: inline-block; white-space: nowrap; }

/* The image that lives in the gap between two words.

   A little squarer than v1's tile, which was 1.5em x 0.74em. Its reels were
   mostly wordmarks; these are mostly standing characters, and a letterbox is
   the one shape a portrait cut-out cannot fill — Stitch came out 28px tall in
   a 97px-wide slot, reading as a blank swatch with a speck in it. */
.us-il-tile {
  position: relative;
  flex: 0 0 auto;
  width: 1.34em;
  height: 0.86em;
  border-radius: 0.14em;
  overflow: hidden;
  transform-origin: center;
  background: var(--lilac-soft);
  will-change: transform;
}

.us-il-slide {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  background: var(--bg);
  overflow: hidden;
}

/* Capped in `em`, not `%`. The tile is sized in em off the headline
   font-size, and a percentage height here resolves against the auto-sized
   grid row rather than the tile — so portrait art (Stitch, Spider-Man)
   renders taller than its own tile and spills past the rounded corners
   mid-transition. em is measured against the same font-size the tile is, so
   the art always fits. Tile is 1.34em x 0.86em; these leave a margin inside. */
.us-il-slide img {
  max-width: 1.16em;
  max-height: 0.72em;
  width: auto;
  height: auto;
  object-fit: contain;
}

.us-il-underline { position: relative; display: inline-block; }
.us-il-underline .us-il-word { display: inline-block; }

/* ── Unicorn watermarks sitting behind the headline ───────────────── */
.us-il-charms {
  position: absolute;
  inset: 0;
  pointer-events: none;
  /* Absolutely-positioned boxes paint above static siblings, so without an
     explicit order the unicorns would cover the type instead of backing it. */
  z-index: 0;
}

.us-il-charm {
  position: absolute;
  display: block;
  width: clamp(96px, 12vw, 178px);
  will-change: transform;
  /* The band's ground is a painted sky rather than flat white, and the
     cut-outs read hot against it at full strength — they are backing the
     statement, not sharing billing with it. */
  opacity: 0.92;
}

.us-il-charm img { width: 100%; height: auto; }

/* Deliberately unmirrored — each pose is already drawn facing the side it sits
   on. See the note on CHARMS in Interlude.tsx.

   Parked *outside* the headline box rather than at a percentage inset into it:
   a percentage is measured against the headline's own width, which grows with
   the viewport faster than the clear space either side of it does, so the pair
   that sat beside the type at 1440px had a horn through the first letter at
   1100px. `right: 100%` pins each one to the edge it belongs to at every
   width; the negative margin tucks it back under the type by a fixed amount,
   which is the overlap a watermark wants. */
.us-il-charm-a { right: 100%; margin-right: var(--charm-gap); top: -34%; }
.us-il-charm-b { left: 100%; margin-left: var(--charm-gap); bottom: -34%; }

/*
 * The gap between a charm and the type, as one number.
 *
 * It used to be a negative margin — the unicorns tucked *under* the first and
 * last letters, which is what a watermark wants and what this stopped being
 * once they were drawn at full opacity: at 1440px the grey one's horn came out
 * of the A. Now they stand clear. It stays a clamp rather than a fixed gap
 * because the slack either side of the headline is what pays for it, and that
 * slack shrinks with the viewport — at the narrow end the pair go back to
 * touching the type rather than off the edge of the band.
 *
 * The `-1.1rem` offset is what keeps the narrow end honest: at 900px the charm
 * is already wider than the clear space beside the headline and only the
 * gutter is absorbing the difference, so the gap there is a few pixels rather
 * than the two-and-a-half rem it reaches on a wide screen. Every stop from
 * 900px up leaves the pair inside the band's own padding.
 */
.us-il-charms { --charm-gap: clamp(0.25rem, 2.6vw - 1.1rem, 2.6rem); }

/* `.wrap` for the same reason as `.eyebrow` above: it must beat the global `.lede`. */
.us-il .us-il-lede {
  /* `--ink-60` is a token for a white ground. On the sky, under drifting
     dust, it was the least readable text in the band. */
  color: rgba(20, 16, 26, 0.8);
  max-width: 54ch;
  line-height: 1.62;
  text-wrap: pretty;
}

.us-il-cta { margin-top: 0.4rem; }

@media (max-width: 899px) {
  .us-il { padding-block: clamp(4rem, 12vh, 7rem); }
  .us-il-inner { max-width: 100%; gap: clamp(1.3rem, 5vw, 2rem); }

  /*
   * The headline is sized off the *line*, not off the viewport ramp above.
   *
   * That ramp's slope exists to leave the unicorn charms somewhere to stand
   * either side of the type — and the charms are `display: none` from here
   * down (see below), so the constraint it is solving for does not exist at
   * this width. What was left was a 1.35rem floor holding the headline at
   * 21.6px on a 390px phone while 60px of the content width sat unused, and
   * two reels rendering at 29px wide inside it.
   *
   * So: fill the measure instead. Line one is the long one — 13.6em with the
   * mobile gap and the tile below, measured rather than counted, because the
   * tile's flex slot is part of the row even while the entrance holds it at
   * `scaleX: 0`. The content box is `100vw - 2 * --gutter`, and the gutter
   * clamp bottoms out at 20px below 500px. `6.85vw - 1.1px` is that quotient
   * against the widened box, with about 7% held back at every width from 320
   * to 899 so the line never reaches the edge.
   *
   * The extra 24px is worth having on a phone: 12px either side is not enough
   * to read as a lost margin, and at 390px it is the difference between 24px
   * and 25.6px of type. The lede keeps the real gutter — only the headline
   * borrows it.
   *
   * The 2.6rem cap is the join: it is where this meets the desktop ramp's
   * value at 900px, so nothing jumps across the breakpoint. Above about 650px
   * the cap is what is in charge and the ramp does nothing.
   */
  .us-il-headline {
    width: calc(100% + 24px);
    margin-inline: -12px;
    font-size: clamp(1.15rem, calc(6.85vw - 1.1px), 2.6rem);
  }

  /* Squarer and larger, in step with the type. These reels are standing
     characters and brand marks, and the desktop letterbox left Rapunzel about
     19px tall in a 29px slot — a coloured swatch with a speck in it. The whole
     tile scales in `em`, so this is a ratio change, not a second size. */
  .us-il-tile { width: 1.55em; height: 0.98em; }
  .us-il-slide img { max-width: 1.36em; max-height: 0.84em; }
  /* The band is narrow here and the copy fills it, so the veil wants to be a
     full-width lift rather than an ellipse that fades out mid-sentence. */
  .us-il-inner::before { inset: -8% -14%; }
  .us-il-line { gap: 0.12em; }

  /*
   * The charms are off below this width, at every size.
   *
   * They are watermarks parked in the clear zones the headline leaves, and
   * that premise only holds while the headline is narrower than the page. On a
   * phone the lines fill the full content width, so there are no clear zones
   * left — shrinking the unicorns and tucking them in just moves them from
   * beside the type to on top of it. A watermark that has to fight the
   * headline for the same pixels is not a watermark. (Same call as v1's hero.)
   */
  .us-il-charms { display: none; }
}

@media (max-width: 599px) {
  .us-il-line { gap: 0.1em; }
}

/* ─── components/art/AuroraField.module.css ─────────────────────────────────────── */
/* ── The band's ground ──────────────────────────────────────────────
   Absolutely placed inside a `position: relative` section and behind
   everything, per the site's local 0 / 1 / 2 stacking. Takes no pointer
   events: the cursor reactivity is read from `window`, not from a hit test,
   so nothing here needs to be a target and nothing here can swallow a click
   meant for the content above it.

   Four washes and a base, laid out as a watercolour sky: warm pink top left,
   cream top right, pale blue low right, lilac low left. `--sky-*` are defined
   in `app/globals.css` beside the rest of the palette. */
.us-aurora-root {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
  background:
    radial-gradient(62% 52% at 16% 10%, var(--sky-blush) 0%, transparent 70%),
    radial-gradient(56% 46% at 84% 16%, var(--sky-cream) 0%, transparent 70%),
    radial-gradient(72% 62% at 74% 80%, var(--sky-blue) 0%, transparent 72%),
    radial-gradient(64% 58% at 20% 84%, var(--sky-lilac) 0%, transparent 72%),
    linear-gradient(158deg, #fdf4fb 0%, #eff3fd 50%, #faeffb 100%);
}

/* ── A wash ─────────────────────────────────────────────────────────
   A soft oval of colour. Deliberately a radial-gradient rather than a solid
   under `filter: blur()`: both look the same, but a blurred layer has to be
   re-rasterised on any frame its geometry changes, and these are on a
   permanent 16–26s loop. A gradient is painted once and only composited
   after that, which is what makes several of them at this size free.

   Blend mode is per-wash (`Blob.blend`): `multiply` for the pigment washes,
   `screen` for the white wisps that lift out of them. */
.us-aurora-blob {
  position: absolute;
  aspect-ratio: 1.3 / 1;
  border-radius: 50%;
  background: radial-gradient(closest-side, var(--blob) 0%, transparent 74%);
  transform-origin: 50% 50%;
  will-change: transform;
}

/* ── Dust ───────────────────────────────────────────────────────────
   `globals.css` resets `img, svg, video { display: block; max-width: 100% }`
   but not canvas, so this sets its own box. The intrinsic size is written in
   JS at device-pixel resolution; these two are the CSS size it is scaled back
   down to. */
.us-aurora-canvas {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
}

/* Under reduced motion the component paints one still frame and starts no
   ticker, so the washes have to hold a composed position rather than the
   identity transform every loop begins from. */
@media (prefers-reduced-motion: reduce) {
  .us-aurora-blob:nth-child(odd) { transform: translate(6%, -4%) scale(1.1); }
  .us-aurora-blob:nth-child(even) { transform: translate(-7%, 5%) scale(1.12); }
}
