/* Hitched (day.html): the hero and the record.

   The poster: 8 VI 22 in three colours behind the two of them, from the
   original wedding illustration. Scrolling flies the camera into the clear
   middle of the left ring (assets/js/hitched.js); the light inside it
   becomes the page the note is pinned to. Then the record, as a four-tier
   cake with the rings on top.
   The illustration keeps its black ink in both themes. At dusk only the
   rays and motion waves turn gold, and the small sparkles go a quiet teal.
   Phones first: the base rules are the phone layout, widened after. */

:root {
  /* the light inside the ring, and the page it opens onto */
  --hx-field: #F0CE84; --hx-field-hi: #FFF4D2; --hx-glow: rgba(255, 246, 222, .7); --hx-star: #FFF8E6;
  --hx-ray: #14110D;
  --hx-t1: #8DBBCD; --hx-t2: #EDC25F; --hx-t3: #DFA7A0;
  --hx-ring: #E2E3AA; --hx-shine: #F8F7EC;
}
[data-theme="dusk"] {
  /* dusk: a teal night with a soft cream light, never gold mixed into teal (that reads as olive) */
  --hx-field: #0F2B33; --hx-field-hi: #3F6A70; --hx-glow: rgba(244, 235, 214, .13); --hx-star: #4C7A80;
  --hx-ray: #E8BE5A;
  --hx-t1: #4E93AC; --hx-t2: #E0B04F; --hx-t3: #C9787F;
}

/* ---- the scroll track and its stage ----------------------------------
   Built for a smooth flight on phones: the artwork is three plain image
   layers the script moves with GPU transforms (no repainting), the vector
   rings are only drawn while the camera is close in, and each frame the
   script writes straight to the few things that move. */
.hx { position: relative; height: 420vh; transition: background-color .3s; }
/* Upright phones: a swipe covers less than a screen there, so the track is
   shorter, about one swipe to the note (hitched.js adds .hx-short). */
.hx.hx-short { height: 240vh; height: 240lvh; }
/* Safari's bar floats over the page, and the page carries on under it: below
   the pinned stage that is this section. Once the light fills the screen the
   section takes its colour, so the strip under the bar is light too, not
   paper (hitched.js adds .hx-lit). */
.hx.hx-lit { background-color: var(--hx-field); }
/* The stage is the tall viewport, the one with the phone's toolbar tucked
   away: at 100svh, a strip of the page below showed under the note once
   Safari shrank its bar. The opening picture is still laid out to the
   short viewport (hitched.js), so nothing starts under the toolbar. */
.hx-stage { position: sticky; top: 0; height: 100vh; height: 100lvh; overflow: hidden; contain: layout paint; }
.hx-date { position: absolute; z-index: 0; left: 0; right: 0; top: 42svh; margin: 0; display: flex; justify-content: center; gap: .04em; translate: 0 -50%; font: 400 min(31vw, 26svh)/.8 var(--display); letter-spacing: -.035em; pointer-events: none; will-change: scale, opacity; }
.hx-date .n { display: inline-block; }
.hx-date .n1 { color: var(--hx-t1); rotate: -5deg; }
.hx-date .n2 { color: var(--hx-t2); rotate: 2deg; translate: 0 -.05em; }
.hx-date .n3 { color: var(--hx-t3); rotate: -2.5deg; }

/* the original drawing, as three image layers. Still (no script, or reduced
   motion) they sit in a box the shape of the scene; in flight the script
   places each one in artwork pixels and moves it. */
.hx-art { position: absolute; z-index: 1; left: 50%; top: 50%; width: min(92vw, calc((100svh - 9rem) * 2180 / 2620)); aspect-ratio: 2180 / 2620; translate: -50% -46%; }
.hx-layer { position: absolute; display: block; max-width: none; height: auto; }
.hx-david   { left: -4.128%;  top: 29.58%; width: 54.13%; }
.hx-yinja   { left: 50%;      top: 29.58%; width: 54.13%; }
.hx-ringart { left: 29.358%;  top: 0;      width: 40.826%; }
.hx-on .hx-art { inset: 0; width: auto; aspect-ratio: auto; translate: none; }
.hx-on .hx-layer { left: 0; top: 0; transform-origin: 0 0; will-change: transform; }

/* the rings, rays and sparkles as smooth vectors, for when the camera is close */
.hx-svg { position: absolute; z-index: 1; inset: 0; width: 100%; height: 100%; display: block; overflow: hidden; visibility: hidden; pointer-events: none; }
.hx-ink path { fill: #14110D; }
/* the drawing keeps its black ink in both themes; only the rays, which are
   light rather than outline, turn gold at dusk so they still show */
.hx-rays path { fill: var(--hx-ray); }
.hx-spark path { fill: var(--hx-ring); }
[data-theme="dusk"] .hx-spark path { fill: #4C7A80; }
[data-theme="dusk"] .hx-s0 path { fill: #E8BE5A; }   /* the big pair by the rings in gold, the small one quiet */
.hx-gold path { fill: var(--hx-ring); }
.hx-shine path { fill: var(--hx-shine); }
.hx-light { opacity: 0; }
.hx-light path { fill: url(#hx-glow); }

.hx-field { position: absolute; z-index: 2; inset: 0; background: radial-gradient(closest-side, var(--hx-glow), transparent) 50% 50% / 130% 90% no-repeat, var(--hx-field); opacity: 0; pointer-events: none; will-change: opacity; }
/* a few stars round the note, twinkling out of step once it is there */
.hx-fstar { position: absolute; fill: var(--hx-star); }
.hx-twinkle .hx-fstar { animation: hx-twinkle 3.4s var(--ease-soft) infinite; }
@keyframes hx-twinkle { 0%, 100% { scale: 1; opacity: 1; } 45% { scale: .62; opacity: .55; } 60% { scale: 1.12; opacity: 1; } }
.hx-f1 { width: 22px; left: 12%; top: 22%; animation-delay: -.4s; }
[data-theme="dusk"] .hx-f3 { fill: #E8BE5A; }
.hx-f3 { width: 30px; right: 11%; top: 18%; animation-delay: -1.1s; }
.hx-f4 { width: 12px; right: 20%; top: 80%; animation-delay: -2.6s; }

/* the note, pinned to the light */
.hx-notewrap { position: absolute; z-index: 3; left: 50%; top: 50%; width: min(calc(100vw - 2.5rem), 34rem); translate: -50% -50%; opacity: 0; isolation: isolate; pointer-events: none; will-change: translate, rotate, opacity; }
.hx-notewrap::before { content: ""; position: absolute; inset: 0; z-index: -1; background: #E4CBC8; border-radius: 8px; rotate: 2.2deg; translate: 7px 9px; }
.hx-note { position: relative; margin: 0; background: #F7F0E0; border: 2px solid #14110D; border-radius: 8px; padding: 2rem 1.4rem 1.35rem; rotate: -1.3deg; }
.hx-note blockquote { margin: 0; }
.hx-note p { margin: 0; font: 500 1.5rem/1.24 var(--hand); color: #14110D; text-wrap: pretty; }
.hx-note figcaption { margin-top: .7rem; text-align: right; font: 700 1.35rem/1 var(--hand); color: #A8391F; rotate: -3deg; }
.hx-pin { position: absolute; top: -16px; left: 50%; width: 30px; translate: -50% 0; fill: #F0CE84; stroke: #14110D; stroke-width: 1.3; }

.hx-cue { position: absolute; z-index: 2; left: 0; right: 0; bottom: max(1rem, env(safe-area-inset-bottom)); display: grid; justify-items: center; gap: .55rem; margin: 0; padding: 0 var(--gutter); text-align: center; font: 500 .69rem/1.3 var(--sans); letter-spacing: .3em; line-height: 1.75; text-transform: uppercase; color: var(--ink-3); }
.hx-cue span { white-space: nowrap; }   /* two lines exactly; Safari otherwise sizes the caption to its narrowest and breaks after the comma */
/* the stage is the tall viewport, but the caption belongs to the short one:
   at the stage's foot it sat under Safari's toolbar, half off the screen,
   on an iPad most of all. Lifted by the toolbar's height, it is always all
   there, just under the drawing. */
.hx-cue { bottom: calc(100lvh - 100svh + max(1rem, env(safe-area-inset-bottom))); }
.hx-cue svg { width: 12px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.hx-on .hx-cue svg { animation: hx-nudge 1.8s var(--ease-soft) infinite; }
.hx-cue.hx-moving svg { animation: none; }
/* a phone held sideways: the drawing fills the height, so the caption sits in
   the corner beside it rather than over the figures (hitched.js adds .hx-squat) */
.hx-squat .hx-cue { right: auto; justify-items: start; text-align: left; padding-left: max(var(--gutter), env(safe-area-inset-left)); }
@keyframes hx-nudge { 50% { translate: 0 5px; } }

/* ---- the record: the cake ---------------------------------------------- */
.hx-record { padding-block: clamp(4.5rem, 10vw, 7.5rem) clamp(4rem, 8vw, 6rem); }
.hx-head { display: grid; justify-items: center; gap: 1rem; text-align: center; margin-bottom: clamp(2.25rem, 5vw, 3.5rem); }
.cake { position: relative; max-width: 460px; margin: 0 auto; display: grid; justify-items: center; }
.cake__topper { width: 52%; height: auto; margin-bottom: -7px; position: relative; z-index: 2; overflow: visible; pointer-events: none; }
.tp-band { fill: #F0CE84; fill-rule: evenodd; stroke: #14110D; stroke-width: 2; }
.tp-glint { fill: none; stroke: #FBF7EE; stroke-width: 3; stroke-linecap: round; }
.tp-star { fill: #F0CE84; stroke: #14110D; stroke-width: 1.6; }
.tp-shine path { fill: none; stroke: #14110D; stroke-width: 2.6; stroke-linecap: round; }
[data-theme="dusk"] .tp-shine path { stroke: #E8BE5A; }
.tier { position: relative; z-index: 1; width: var(--w); min-width: 11rem; margin-top: -2px; background: var(--c); color: #14110D; border: 2px solid #14110D; border-radius: 12px 12px 6px 6px; padding: 1.5rem .9rem .9rem; text-align: center; display: grid; gap: .2rem; }
.tier:last-of-type { width: 100%; }
.tier__icing { position: absolute; left: 0; top: 0; width: 100%; height: 18px; overflow: visible; border-radius: 10px 10px 0 0; }
.tier__icing .fill { fill: #FBF7EE; }
.tier__icing .edge { fill: none; stroke: #14110D; stroke-width: 2; vector-effect: non-scaling-stroke; stroke-linejoin: round; }
.tier__k { font: 500 .6rem/1.3 var(--sans); letter-spacing: .24em; text-transform: uppercase; }
.tier__v { font: 400 1.3rem/1.1 var(--display); }
.tier__note { font: 400 .8rem/1.4 var(--sans); color: #3A3226; margin-top: .15rem; }
.tier__arrow { display: none; }
.cake__plate { width: 108%; height: 14px; margin-top: -2px; border: 2px solid #14110D; border-radius: 999px; background: #EFE4CB; position: relative; z-index: 1; }
.cake__foot { width: 30%; margin-top: -2px; overflow: visible; }
.cake__foot path { fill: #EFE4CB; stroke: #14110D; stroke-width: 2; stroke-linejoin: round; }

/* the cake stacks itself, bottom tier first, when it comes into view */
.cake.hx-armed:not(.go) .tier, .cake.hx-armed:not(.go) .cake__topper { opacity: 0; }
.cake.go .tier { animation: hx-drop .75s cubic-bezier(.3, 1.45, .5, 1) both; animation-delay: calc(var(--i) * 140ms); }
.cake.go .cake__topper { animation: hx-pop .6s cubic-bezier(.3, 1.6, .5, 1) .66s both; }
@keyframes hx-drop { from { translate: 0 -90px; opacity: 0; } 25% { opacity: 1; } to { translate: 0 0; opacity: 1; } }
@keyframes hx-pop { from { scale: .2; rotate: -24deg; opacity: 0; } to { scale: 1; rotate: 0deg; opacity: 1; } }

/* ---- wider screens ------------------------------------------------------ */
@media (min-width: 700px) {
  .hx-note { padding: 2.4rem 2.2rem 1.6rem; }
  .hx-note p { font-size: 1.85rem; }
  .hx-notewrap::before { translate: 10px 12px; }
  .tier__v { font-size: 1.5rem; }
}
@media (min-width: 1000px) {
  .tier { padding: 1.6rem 1rem 1rem; }
  .tier__note { position: absolute; top: 50%; translate: 0 -40%; width: 14ch; margin: 0; font: 600 1.4rem/1.04 var(--hand); color: var(--ink-2); }
  .tier__note--l { right: calc(100% + 64px); text-align: right; rotate: -3deg; }
  .tier__note--r { left: calc(100% + 64px); text-align: left; rotate: 3deg; }
  .tier__arrow { display: block; position: absolute; top: 30%; width: 54px; height: 28px; fill: none; stroke: var(--ink-2); stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
  .tier__note--l .tier__arrow { right: -60px; }
  .tier__note--r .tier__arrow { left: -60px; scale: -1 1; }
  /* Once the cake has stacked, the notes are written in one at a time,
     reading down it: each comes up out of a soft blur, like ink taking,
     and then its arrow is drawn from the note to its tier, a pen stroke.
     (On a phone the notes are inside the tiers and drop with them.) */
  .cake.hx-armed:not(.go) .tier__note { opacity: 0; }
  .cake.hx-armed:not(.go) .tier__arrow path { stroke-dasharray: 1; stroke-dashoffset: 1; }
  .cake.go .tier__note {
    --at: calc(1.15s + (3 - var(--i)) * 300ms);
    animation: hx-write .8s cubic-bezier(.16, 1, .3, 1) var(--at) both;
  }
  /* the line first, then the head that finishes it: one path, the two were
     drawn at once, and a half-drawn line already wore its arrowhead */
  .cake.go .tier__arrow path { stroke-dasharray: 1; }
  .cake.go .tier__line { animation: hx-ink .5s cubic-bezier(.65, 0, .35, 1) calc(var(--at) + .35s) both; }
  .cake.go .tier__head { animation: hx-ink .22s cubic-bezier(.33, 1, .68, 1) calc(var(--at) + .82s) both; }
}
@keyframes hx-write { from { opacity: 0; filter: blur(4px); transform: translateY(6px); } to { opacity: 1; filter: blur(0); transform: none; } }
@keyframes hx-ink { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }

/* ---- the rest of the page, in the same hand -------------------------------
   Every section opens the same way: a small flat drawing in the cake's
   language (gold and cream fills, a 2px ink keyline), then the heading
   centred, then the intro. The drawings keep black ink in both themes. */
.hd-head { display: grid; justify-items: center; gap: 1rem; text-align: center; margin-bottom: clamp(2.25rem, 5vw, 3.5rem); }
.hd-head .lede { margin: 0 auto; max-width: 40ch; text-align: center; text-wrap: balance; }
.hd-mark { display: block; width: 52px; height: 52px; rotate: var(--t, 0deg); }
.hd-mark svg { width: 100%; height: 100%; overflow: visible; }
.hd-mark svg * { stroke: #14110D; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.hd-mark svg [stroke-width="1.6"] { stroke-width: 1.6; }

/* the film, in a little TV set: blue cabinet, gold aerials, two knobs */
.tv { position: relative; max-width: 780px; margin: 0 auto; padding-top: 50px; }
.tv__aerial { position: absolute; z-index: 0; top: 0; left: 50%; width: 120px; translate: -50% 0; overflow: visible; }
.tv__rod { fill: none; stroke: #14110D; stroke-width: 2.4; stroke-linecap: round; }
.tv__tip { fill: #F0CE84; stroke: #14110D; stroke-width: 1.6; }
.tv__dome { fill: #F0CE84; stroke: #14110D; stroke-width: 2; }
.tv__block { position: absolute; z-index: 0; inset: 50px 0 14px; background: #F0CE84; border-radius: 22px; rotate: 1.4deg; translate: 8px 10px; }
.tv__body { position: relative; z-index: 1; display: grid; gap: 12px; padding: 12px; background: #8DBBCD; border: 2px solid #14110D; border-radius: 22px; }
.tv .tube { border: 2px solid #14110D; border-radius: 12px; box-shadow: none; transform: none; }
@media (hover: hover) { .tv .tube:hover { transform: none; box-shadow: none; } }
.tv__panel { display: flex; align-items: center; gap: 10px; padding: 0 4px 2px; }
.tv__knob { position: relative; width: 22px; height: 22px; border-radius: 50%; background: #F0CE84; border: 2px solid #14110D; rotate: -30deg; transition: rotate .6s var(--ease); }
.tv__knob::after { content: ""; position: absolute; left: 50%; top: 2px; width: 2px; height: 7px; translate: -50% 0; border-radius: 1px; background: #14110D; }
.tv__knob--b { background: #E4CBC8; rotate: 60deg; }
@media (hover: hover) { .tv:hover .tv__knob { rotate: 40deg; } }
@media (hover: hover) { .tv:hover .tv__knob--b { rotate: -20deg; } }
.tv__grille { display: grid; gap: 4px; margin-left: auto; }
.tv__grille i { display: block; width: 38px; height: 4px; border-radius: 2px; background: #14110D; }
.tv__feet { position: relative; z-index: 1; display: flex; justify-content: space-between; width: 62%; margin: -2px auto 0; }
.tv__feet i { display: block; width: 26px; height: 14px; background: #14110D; border-radius: 0 0 8px 8px; }
.hd-film__btns { margin-top: clamp(2.5rem, 6vw, 3.5rem); }
/* the page's buttons wear the cake's gold rather than the old oxblood */
body[data-page="day"] main .btn:not(.btn--ghost) { --btn-bg: #F0CE84; --btn-fg: #14110D; }
@media (min-width: 760px) {
  .tv { padding-top: 58px; }
  .tv__aerial { width: 140px; }
  .tv__block { inset: 58px 0 14px; }
  .tv__body { grid-template-columns: minmax(0, 1fr) 76px; gap: 16px; padding: 16px; border-radius: 26px; }
  .tv__panel { flex-direction: column; justify-content: center; gap: 18px; padding: 0; }
  .tv__knob { width: 34px; height: 34px; }
  .tv__knob::after { height: 11px; top: 3px; }
  .tv__grille { margin: 6px 0 0; }
  .tv__grille i { width: 34px; }
}

/* the vows: two cards of clean cream stationery with black ink, the colour
   only in the block behind, the label and the marker. Like the note and the
   cake they stay lit in dusk, rather than mixing their colour into the dark
   (which read as olive). Colours are fixed so they hold in both themes. */
.hd-vows .vows__slot:first-child { --off: #8DBBCD; }
.hd-vows .vows__slot:last-child  { --off: #F0CE84; }
.hd-vows .vow { background: #FBF7EE; color: #14110D; border-color: #14110D; }
.hd-vows .vow::before { border-color: color-mix(in srgb, var(--off) 70%, #FBF7EE); }
.hd-vows .vow__pic { background: #FBF7EE; border-color: #14110D; box-shadow: 4px 4px 0 color-mix(in srgb, var(--off) 80%, #14110D); }
.hd-vows .vow__to { color: #14110D; background: color-mix(in srgb, var(--off) 55%, #FBF7EE); border-color: #14110D; }
.hd-vows .vow__text { color: #14110D; }
.hd-vows .vow__sign { filter: none; }
[data-theme="dusk"] .hd-vows .vow__promise { background-image: linear-gradient(color-mix(in srgb, var(--off) 75%, transparent), color-mix(in srgb, var(--off) 75%, transparent)); background-position: 0 88%; background-size: 0% .42em; }
[data-theme="dusk"] .hd-vows .is-in .vow__promise { background-size: 100% .42em; }

/* ---- still: no script, or reduced motion ---------------------------------
   The script adds .hx-on when it is going to fly the camera. Without it the
   hero is a still poster one screen tall, and the note is set beneath it. */
.hx:not(.hx-on) { height: auto; }
.hx:not(.hx-on) .hx-stage { position: relative; height: auto; overflow: visible; padding: 100svh 0 clamp(3rem, 8vw, 5rem); }
.hx:not(.hx-on) .hx-art { top: 50svh; }
.hx:not(.hx-on) .hx-field, .hx:not(.hx-on) .hx-svg, .hx:not(.hx-on) .hx-cue svg { display: none; }
.hx:not(.hx-on) .hx-cue { top: calc(100svh - 3.25rem); bottom: auto; }
.hx:not(.hx-on) .hx-notewrap { position: relative; left: auto; top: auto; margin: 0 auto; translate: none; rotate: none; opacity: 1; }
.hx:not(.hx-on) .hx-date { top: 30svh; }

@media (prefers-reduced-motion: reduce) {
  .hx-fstar, .hx-cue svg { animation: none !important; }
}
