/* ==========================================================================
   Kimi Franco
   Brand: Wide Sky #009DC9 / Safe Space #E8DBCB / Italiana + Jost.
   Sections are separated by a change of paper, never by a rule.
   ========================================================================== */

:root {
  --sky:        #009dc9;
  --sky-deep:   #007ea3;
  --sky-wash:   #e6f5fa;
  --sand:       #e8dbcb;
  --sand-soft:  #f4ece1;
  --sand-line:  #d8c7b2;
  --ink:        #14171a;
  --ink-soft:   #5d6570;
  --ink-faint:  #8b939d;
  --paper:      #ffffff;

  /* Deep Umber: Safe Space taken down to near-black, so the dark surfaces
     belong to the palette instead of being a neutral black beside it.
     Kept separate from --ink, which is text and stays neutral. */
  --deep:       #2c241e;
  --deep-hover: #1e1813;

  --display: "Italiana", Georgia, serif;
  --body:    "Jost", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;

  --d1: clamp(2.55rem, 4.6vw, 4rem);
  --d2: clamp(1.9rem, 3.6vw, 3.05rem);
  --d3: clamp(1.35rem, 2.2vw, 1.9rem);

  --wrap:   1220px;
  --gutter: clamp(20px, 5vw, 56px);
  --bay:    clamp(72px, 11vw, 150px);

  --radius:    22px;
  --radius-sm: 14px;

  --ease: cubic-bezier(.22, .61, .36, 1);
}

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

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font: 400 1.0625rem/1.66 var(--body);
  letter-spacing: .004em;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
body.nav-open { overflow: hidden; }

img, svg, video { max-width: 100%; display: block; }
a { color: inherit; }

/* Read aloud, never drawn. */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

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

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 200;
  background: var(--ink); color: #fff; padding: .8rem 1.2rem;
  font: 600 .8rem var(--body);
}
.skip:focus { left: var(--gutter); top: .6rem; }

/* --- Type ---------------------------------------------------------------- */

h1, h2, h3, h4 {
  font-family: var(--display);
  font-weight: 400;
  letter-spacing: .005em;
  margin: 0;
  text-wrap: balance;
}

h1 { font-size: var(--d1); line-height: .98; }
h2 { font-size: var(--d2); line-height: 1.04; }
h3 { font-size: var(--d3); line-height: 1.15; }

/* Jost light-italic against Italiana. Jost is Futura-shaped, so its circular
   bowls echo the wordmark's own geometry inside a single line. */
.accent {
  font-family: var(--body);
  font-weight: 200;
  font-style: italic;
  font-size: .82em;
  letter-spacing: -.005em;
}

.eyebrow {
  font: 600 .69rem/1 var(--body);
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--sky);
  margin: 0 0 1.6rem;
}
.eyebrow--quiet { color: var(--ink-faint); }
.on-sky .eyebrow, .section--sky .eyebrow { color: rgba(255, 255, 255, .82); }

.lede {
  font-size: clamp(1.08rem, 1.5vw, 1.3rem);
  line-height: 1.6;
  color: var(--ink-soft);
  max-width: 46ch;
}
.on-sky .lede, .section--sky .lede { color: rgba(255, 255, 255, .9); }

p { margin: 0 0 1.15rem; }
p:last-child { margin-bottom: 0; }

/* --- Shell --------------------------------------------------------------- */

.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.section {
  position: relative;
  padding-block: var(--bay);
  /* The paper grain multiplies into whatever colour the section carries. */
  background-image: url("../img/paper.png");
  background-size: 320px 320px;
  background-repeat: repeat;
  background-blend-mode: multiply;
}
/* The header is fixed, so anchored sections need to clear it. */
.section[id], [id="top"] { scroll-margin-top: 84px; }

.section--paper { background-color: var(--paper); }
.section--sand  { background-color: var(--sand); }
.section--soft  { background-color: var(--sand-soft); }
.section--sky   { background-color: var(--sky); color: #fff; }
.on-sky { color: #fff; }

.section-head { max-width: 44ch; margin-bottom: clamp(2.75rem, 5vw, 4.5rem); }
/* Sized in rem, not ch: the display face makes ch far too wide to reason about. */
.section-head--wide { max-width: 54rem; }
.section-head--centre { margin-inline: auto; text-align: center; }
.section-head--centre .lede { margin-inline: auto; }

/* --- Buttons ------------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  gap: .6rem;
  padding: 1.02rem 2.05rem;
  border: 1px solid transparent;
  border-radius: 999px;
  font: 600 .795rem/1 var(--body);
  letter-spacing: .11em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  transition: transform .32s var(--ease), background-color .32s var(--ease),
              color .32s var(--ease), border-color .32s var(--ease),
              box-shadow .32s var(--ease);
}
.btn:hover { transform: translateY(-2px); }
.btn .arrow { transition: transform .32s var(--ease); }
.btn:hover .arrow { transform: translateX(4px); }

.btn--primary {
  background: var(--sky);
  color: #fff;
  box-shadow: 0 10px 26px -14px rgba(0, 125, 163, .85);
}
.btn--primary:hover { background: var(--sky-deep); box-shadow: 0 16px 34px -14px rgba(0, 125, 163, .9); }

.btn--deep { background: var(--deep); color: #fff; }
.btn--deep:hover { background: var(--deep-hover); }

.btn--light { background: #fff; color: var(--sky-deep); }
.btn--light:hover { color: var(--ink); }

.btn--ghost { border-color: currentColor; color: inherit; }
.btn--ghost:hover { background: var(--deep); border-color: var(--deep); color: #fff; }
.on-sky .btn--ghost:hover { background: #fff; border-color: #fff; color: var(--sky-deep); }

/* Long CTA labels need the room back on narrow phones. */
@media (max-width: 420px) {
  .btn { padding: .95rem 1.5rem; font-size: .74rem; letter-spacing: .08em; }
}

.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: .85rem 1.1rem;
  align-items: center;
  margin-top: 2.4rem;
}
.btn-row--centre { justify-content: center; }

.text-link {
  font: 500 .82rem/1 var(--body);
  letter-spacing: .1em;
  text-transform: uppercase;
  text-decoration: none;
  border-bottom: 1px solid currentColor;
  padding-bottom: .4rem;
  transition: opacity .3s var(--ease);
}
.text-link:hover { opacity: .6; }

/* --- Header -------------------------------------------------------------- */

.site-header {
  position: fixed;
  inset: 0 0 auto;
  z-index: 100;
  padding-block: 1.15rem;
  transition: background-color .4s var(--ease), box-shadow .4s var(--ease),
              padding .4s var(--ease);
}
.site-header.is-stuck {
  background: rgba(255, 255, 255, .93);
  backdrop-filter: saturate(1.4) blur(14px);
  box-shadow: 0 1px 0 rgba(20, 23, 26, .07);
  padding-block: .75rem;
}

.site-header .wrap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
}

.brand { display: inline-flex; color: var(--ink); text-decoration: none; }
.brand svg { height: clamp(17px, 2.1vw, 22px); width: auto; }

.site-nav { display: flex; align-items: center; gap: clamp(1.1rem, 2.4vw, 2.1rem); }
.site-nav a {
  font: 500 .74rem/1 var(--body);
  letter-spacing: .13em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--ink);
  transition: color .3s var(--ease);
}
.site-nav a:hover { color: var(--sky); }
.site-nav .btn { color: #fff; padding: .8rem 1.5rem; }
.site-nav .btn:hover { color: #fff; }

.nav-toggle {
  display: none;
  width: 42px; height: 34px;
  border: 0; background: none; padding: 0; cursor: pointer;
  position: relative; z-index: 2;
}
.nav-toggle span {
  display: block; height: 1px; background: var(--ink); margin: 8px 0;
  transition: transform .34s var(--ease), opacity .3s var(--ease);
}
.nav-open .nav-toggle span:nth-child(1) { transform: translateY(9px) rotate(45deg); }
.nav-open .nav-toggle span:nth-child(2) { opacity: 0; }
.nav-open .nav-toggle span:nth-child(3) { transform: translateY(-9px) rotate(-45deg); }

@media (max-width: 900px) {
  .nav-toggle { display: block; }
  .site-nav {
    position: fixed;
    inset: 0 0 0 auto;
    width: min(84vw, 340px);
    flex-direction: column;
    align-items: flex-start;
    justify-content: center;
    gap: 1.6rem;
    padding: 2rem var(--gutter);
    background: var(--paper);
    box-shadow: -20px 0 60px -30px rgba(20, 23, 26, .5);
    transform: translateX(100%);
    transition: transform .44s var(--ease);
  }
  .site-nav a { font-size: .92rem; }
  .nav-open .site-nav { transform: none; }
}

/* --- Hero ---------------------------------------------------------------- */

.hero {
  padding-top: clamp(140px, 18vw, 210px);
  padding-bottom: clamp(70px, 9vw, 120px);
  background-color: var(--paper);
}

.hero-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.12fr) minmax(0, .88fr);
  gap: clamp(2.5rem, 5vw, 5rem);
  align-items: center;
}

.hero h1 { margin-bottom: 1.6rem; }
.hero .lede { max-width: 42ch; }

.hero-marks {
  display: flex;
  gap: 1.7rem;
  margin: 3.2rem 0 0;
  padding-top: 1.7rem;
  border-top: 1px solid var(--sand-line);
  flex-wrap: wrap;
}
.hero-marks div { min-width: 92px; }
.hero-marks dt {
  font: 600 .66rem/1 var(--body);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-bottom: .55rem;
}
.hero-marks dd { margin: 0; font-family: var(--display); font-size: 1.5rem; line-height: 1; }

/* Media slot: the moodboard's isolated subject against a vast single colour. */
.media-frame {
  position: relative;
  aspect-ratio: 9 / 16;
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--sky);
  isolation: isolate;
}
.media-frame--portrait { aspect-ratio: 4 / 5; }
.media-frame--sand { background: var(--sand); }
.media-frame > img,
.media-frame > video {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
}
.media-frame .k-wash {
  position: absolute; inset: 0;
  background: url("../img/k-tile-white.svg") 0 0 / 150px repeat;
  opacity: .16;
}
.media-frame--sand .k-wash {
  background-image: url("../img/k-tile-sky.svg");
  opacity: .22;
}
.media-frame .placeholder {
  position: absolute; inset: 0;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: 1.2rem; text-align: center; padding: 2rem;
  color: #fff;
}
.media-frame--sand .placeholder { color: var(--sky-deep); }
.media-frame .placeholder svg { width: clamp(52px, 8vw, 76px); height: auto; }
.media-frame .placeholder span {
  font: 500 .68rem/1.5 var(--body);
  letter-spacing: .18em;
  text-transform: uppercase;
  opacity: .85;
}

@media (max-width: 880px) {
  .hero-grid { grid-template-columns: 1fr; }
  .hero-media { max-width: 380px; margin-inline: auto; width: 100%; }
}

/* --- Section 2: problem cards -------------------------------------------- */

.curious-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1.2rem, 2.4vw, 2.2rem);
  align-items: start;
}
/* Staggered columns, echoing the reference layout. */
.curious-grid > *:nth-child(3n + 2) { margin-top: clamp(1.6rem, 4vw, 3.4rem); }

/* Bubble and face together are one item, so the stagger moves the pair. */
.curious-said {
  display: grid;
  justify-items: center;
}

.curious-card {
  position: relative;
  width: 100%;
  background: rgba(255, 255, 255, .78);
  border: 1px solid var(--sand-line);
  border-radius: var(--radius);
  padding: clamp(1.5rem, 2.4vw, 2.05rem);
}
.curious-card h3 { font-size: 1.32rem; margin-bottom: .85rem; }
.curious-card p { font-size: .96rem; color: var(--ink-soft); }

/*
   The bubble's tail. It was already here as a chevron carrying the eye from
   one staggered card to the next; now it points at whoever said the thing,
   which is the same mark doing a better job.
*/
.curious-card::after {
  content: "";
  position: absolute;
  left: 50%; bottom: -1.35rem;
  width: 11px; height: 11px;
  border: solid var(--ink-faint);
  border-width: 0 1px 1px 0;
  transform: translateX(-50%) rotate(45deg);
}

/*
   The face under the tail. Near-white like the bubble rather than sand: this
   sits directly on a sand section, so a sand disc would have no edge at all.
   Fixed size, so it stays a circle whatever the card above it does.
*/
.curious-face {
  display: grid;
  place-items: center;
  width: 2.9rem;
  height: 2.9rem;
  margin-top: 2.15rem;
  border-radius: 50%;
  background: rgba(255, 255, 255, .78);
  border: 1px solid var(--sand-line);
  color: var(--deep);
}
.curious-face svg { width: 76%; height: 76%; display: block; }

.curious-answer {
  margin-top: clamp(3.5rem, 7vw, 6rem);
  padding: clamp(2rem, 4vw, 3.4rem);
  border-radius: var(--radius);
  background: var(--deep);
  color: #fff;
  display: grid;
  /* The heading carries its own line break and each of its two sentences has
     to fit on one line; below about this share of the row the first sentence
     wraps after "is", which is not a break anybody chose. */
  grid-template-columns: minmax(0, 1.14fr) minmax(0, 1fr);
  gap: clamp(1.6rem, 4vw, 3rem);
  align-items: center;
}
.curious-answer h3 { font-size: clamp(1.55rem, 2.9vw, 2.35rem); margin-bottom: .9rem; }
.curious-answer p { color: rgba(255, 255, 255, .76); max-width: 56ch; }
/* Wide Sky goes muddy against umber; Safe Space is the natural partner. */
.curious-answer .btn--primary { background: var(--sand); color: var(--deep); box-shadow: none; }
.curious-answer .btn--primary:hover { background: var(--sand-soft); color: var(--deep); }
.answer-said .btn { margin-top: clamp(1.4rem, 2.5vw, 2rem); }

/* One answer per problem above, paired by position. */
.fix-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(.6rem, 1.2vw, .9rem);
  list-style: none;
  margin: 0;
  padding: 0;
}
/*
   Faint enough to stay a tile on the umber rather than reading as a second
   panel sitting on the first. A solid fill here would do the latter.
*/
.fix {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: .75rem;
  align-items: start;
  padding: clamp(.85rem, 1.4vw, 1.05rem);
  border-radius: calc(var(--radius) * .55);
  background: rgba(255, 255, 255, .055);
  border: 1px solid rgba(255, 255, 255, .1);
}
/* The 56ch cap belongs to the paragraph on the other side, not to a tile. */
.fix p {
  max-width: none;
  font-size: .87rem;
  line-height: 1.45;
  color: rgba(255, 255, 255, .82);
}

/* Sand on umber again — the same pairing the button uses, for the same reason. */
.fix-mark {
  display: grid;
  place-items: center;
  flex: none;
  width: 1.55rem;
  height: 1.55rem;
  border-radius: .42rem;
  background: var(--sand);
  color: var(--deep);
  font-size: .8rem;
  line-height: 1;
}

@media (max-width: 900px) {
  .curious-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .curious-grid > *:nth-child(3n + 2) { margin-top: 0; }
  .curious-grid > *:nth-child(even) { margin-top: clamp(1.6rem, 4vw, 3.4rem); }
  /* Six tiles beside a heading needs width the panel no longer has. */
  .curious-answer { grid-template-columns: 1fr; align-items: start; }
}
@media (max-width: 620px) {
  .curious-grid { grid-template-columns: 1fr; gap: clamp(1.8rem, 4vw, 2.4rem); }
  .curious-grid > * { margin-top: 0 !important; }
  .fix-grid { grid-template-columns: 1fr; }
}

/* --- Section 3: the pinboard ---------------------------------------------- */
/*
   Five notes pinned to a board in a zigzag, linked by a dashed trail, with
   the client photographs taped into the space the zigzag leaves empty.

   The surface is a variant, not a rewrite: PURSUIT_SURFACE in config.php puts
   .pinboard--sky (blue paper) or .pinboard--cork (corkboard) on the section,
   and everything pinned to it is identical either way. Each variant supplies
   four custom properties — the trail colour and two pin colours — and nothing
   below this line needs to know which one is in play.
*/

.pinboard {
  --note:     #fdfaf5;
  --row-gap:  clamp(3.25rem, 6vw, 5.5rem);
  /* Endpoints sit hard in the corners of the mask box, so that once the box is
     overlapped by a card at each end the dashes disappear under the paper
     rather than stopping just short of it. */
  --trail-path: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 260 92'%3E%3Cpath d='M2 3 C 126 3 84 89 258 89' fill='none' stroke='%23000' stroke-width='3' stroke-linecap='round' stroke-dasharray='1 13'/%3E%3C/svg%3E");
}

/*
   The vignette.

   Written as an opaque white-to-grey ramp multiplied into the surface, not as
   a translucent dark wash laid over it. Multiply means white is "leave this
   alone" and every step towards grey is a stop of light lost, so the falloff
   is set by choosing how dark the far end goes and the colour underneath comes
   through it unchanged — Wide Sky deepens into Wide Sky rather than silting up
   towards grey, which is what a black wash at low opacity does to a saturated
   colour. It was an `overlay` layer at .34 before, which on a colour this
   strong was doing almost nothing visible.

   120% 78% makes it an ellipse wider than the section and shorter than it, so
   the light falls off towards the top and bottom edges faster than the sides.
   The section is far taller than it is wide; a circular vignette on a shape
   this tall would crush the top and bottom and never reach the sides at all.

   Centred at 42% rather than 50% so the brightest part sits just above the
   middle, under the heading, and the board darkens as it goes down.
*/
.pinboard {
  --vignette: radial-gradient(118% 76% at 50% 42%,
    #ffffff 0%, #ffffff 26%, #c2ccd2 58%, #7d8e98 82%, #4e5f6a 100%);
}

/* Blue paper, ruled like a notebook.

   Read from the bottom of the list up, which is the order they stack: the
   vignette darkens the Wide Sky towards the edges, the rules are drawn onto it,
   and the grain is multiplied over both. That order matters — grain last means
   the rules sit *in* the paper rather than floating on top of it, which is the
   difference between ruled paper and a blue panel with lines drawn on it.

   The grain is carried twice at different scales, once close and once coarse,
   because a single pass of the tile multiplied into a colour this saturated
   disappears and the section goes back to reading as flat paint.

   30px rules: close enough to read as a notebook, far enough apart that they
   never line up with a line of body copy and make it look mis-set. Tighter
   than this and the section stops reading as ruled paper and starts reading
   as a stripe. */
.pinboard--sky {
  --trail: rgba(255, 255, 255, .58);
  --pin-a: #2c241e;
  --pin-b: #e8dbcb;
  background-image:
    url("../img/paper.png"),
    url("../img/paper.png"),
    repeating-linear-gradient(to bottom,
      rgba(255, 255, 255, .11) 0 1px, rgba(255, 255, 255, 0) 1px 30px),
    var(--vignette);
  background-size:   260px 260px, 620px 620px, 100% 100%, 100% 100%;
  background-repeat: repeat, repeat, no-repeat, no-repeat;
  background-blend-mode: multiply, multiply, normal, multiply;
}

/* Corkboard. Wide Sky comes back as the pin colour, which is the only place
   the brand blue appears once the surface stops being blue. */
.section--cork { background-color: #c49a67; color: var(--deep); }
.pinboard--cork {
  --trail: rgba(44, 36, 30, .62);
  --pin-a: #009dc9;
  --pin-b: #2c241e;
  background-image:
    var(--vignette),
    url("../img/cork.jpg");
  background-size:   100% 100%, 384px 384px;
  background-repeat: no-repeat, repeat;
  background-blend-mode: multiply, normal;
}
/* Wide Sky on tan is nowhere near readable, so the cork board takes its
   eyebrow and lede from Deep Umber instead. */
.pinboard--cork .eyebrow { color: rgba(44, 36, 30, .70); }
.pinboard--cork .lede    { color: rgba(44, 36, 30, .84); }

/* --- The board ----------------------------------------------------------- */

.pinboard-rows {
  list-style: none;
  margin: clamp(2.5rem, 4vw, 3.5rem) 0 0;
  padding: 0;
  display: grid;
  gap: var(--row-gap);
}

.pinrow {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(1.5rem, 4vw, 3.5rem);
  align-items: start;
  --note-tilt: 0deg;
  --photo-tilt: 0deg;
  --tape-tilt: -3deg;
}
.pinrow--left  { --note-tilt: -1.4deg; }
.pinrow--right { --note-tilt:  1.4deg; }

/*
   The slot spans the whole row and the note is pushed to one side inside it,
   rather than the slot sitting in a column. The trail hangs off the slot and
   has to reach across to the far note, so its 25%/75% ends have to be
   percentages of the row; measured against a single column they would both
   land in the gap.

   Photographs stay real grid items in the opposite column, so they can never
   collide with a note however tall they get — which is the whole reason the
   slot exists. Explicit row 1 on both, or the right-hand note drops below the
   photograph instead of sitting beside it.
*/
.note-slot { grid-column: 1 / -1; grid-row: 1; }
.pinrow--left  .note { margin-right: auto; }
.pinrow--left  .polaroid,
.pinrow--left  .polaroid-pair { grid-column: 2; grid-row: 1; }
.pinrow--right .note { margin-left: auto; }
.pinrow--right .polaroid,
.pinrow--right .polaroid-pair { grid-column: 1; grid-row: 1; }

/*
   Two prints pegged up side by side, clear of one another. The gap is a little
   wider than it looks like it needs to be: both prints are tilted, and it is
   the corners that come closest, not the edges.
*/
.polaroid-pair {
  display: flex;
  align-items: flex-start;
  justify-content: center;
  justify-self: center;
  gap: clamp(1.6rem, 2.6vw, 2.4rem);
}
.polaroid-pair > :nth-child(1) { --photo-tilt: var(--pair-tilt-a, -2.8deg); }
/* The second hangs lower on a longer string, off the same rail. */
.polaroid-pair > :nth-child(2) {
  --photo-tilt: var(--pair-tilt-b, 3.4deg);
  --hang-drop: 2.6rem;
}

/*
   Every photograph is a different size and hangs at its own angle. A board
   where they all match reads as a printed grid rather than three prints
   somebody pinned up — and real prints come back from the lab in whatever
   shape they were shot in. One portrait, one landscape, one square.

   Widths are capped so no photograph stands much more than 55px taller than
   the note beside it. That is not a tidiness rule: the row is as tall as its
   tallest item, so an oversized print would push the row's bottom edge far
   below the note and drag the layout around it.
*/
.pinrow:nth-child(1) {
  --photo-tilt:  2.6deg; --tape-tilt: -5deg;
  --photo-w: clamp(10rem, 15vw, 13rem); --photo-ar: 4 / 5;    /* portrait */
}
/* The hanging pair. Narrower than the others twice over: each print gives up
   3.1rem to its string before it starts, and there are two of them side by
   side in one column. */
.pinrow:nth-child(2) {
  --tape-tilt: 0deg;
  --photo-w: clamp(6.6rem, 9vw, 8.4rem); --photo-ar: 4 / 5;    /* portrait */
}
.pinrow:nth-child(3) {
  --photo-tilt: -2.3deg; --tape-tilt:  4deg;
  --photo-w: clamp(12rem, 18vw, 16rem); --photo-ar: 5 / 4;    /* landscape */
}
.pinrow:nth-child(4) {
  --photo-tilt:  1.9deg; --tape-tilt: -2deg;
  --photo-w: clamp(9rem, 12.5vw, 11rem); --photo-ar: 1;       /* square */
}

/* The dashed trail running from one note to the next. Drawn as a mask so a
   single shape serves both surfaces, taking its colour from --trail.

   It hangs off .note-slot, whose height is the note's height, rather than off
   the row, whose height is that of the taller of the note and the photograph.
   Anchored to the row, the trail's start moves every time a photograph changes
   size — which is exactly what happens now that the three are different shapes.
   Anchored to the note, the photographs can be any size at all.

   Vertically it starts 3rem above the note's own bottom edge and runs a long
   way past the next note's top. Overshooting costs nothing, because the far end
   is under a card either way; falling short leaves the dashes hanging in open
   air. Horizontally the box spans 25%-75% of the row while the notes reach in
   from 0-39% and 61-100%, so each end is overlapped by the card it belongs to.

   The z-index pair is what puts it behind rather than over. .note-slot is left
   at z-index auto so it creates no stacking context: the trail then competes
   directly with the cards of every row, including the next row's note, which it
   has to run beneath. Without the pair it is the last positioned thing in the
   row and paints over the paper. */
.note-slot { position: relative; }
.note-slot::after {
  content: "";
  position: absolute;
  z-index: 0;
  top: calc(100% - 3rem);
  height: calc(var(--row-gap) + 10rem);
  left: 25%;
  right: 25%;
  background-color: var(--trail);
  -webkit-mask: center / 100% 100% no-repeat var(--trail-path);
          mask: center / 100% 100% no-repeat var(--trail-path);
  pointer-events: none;
}
.note, .polaroid { z-index: 1; }
/* Right-hand rows lead back the other way. */
.pinrow--right .note-slot::after { transform: scaleX(-1); }
/* The last note has nothing to lead to; without this its trail runs on off the
   bottom of the section and past the button. */
.pinrow:last-child .note-slot::after { content: none; }

/* --- A note -------------------------------------------------------------- */

.note {
  position: relative;
  /* 47% keeps the note inside its half of the row even though its slot spans
     the whole of it, so it can never run under the photograph opposite. */
  width: min(27rem, 47%);
  margin: 0;
  padding: clamp(2.1rem, 3vw, 2.7rem) clamp(1.7rem, 2.4vw, 2.2rem) clamp(1.8rem, 2.6vw, 2.3rem);
  background: var(--note);
  color: var(--ink);
  border-radius: 3px;
  box-shadow:
    0 1px 1px rgba(44, 36, 30, .14),
    0 14px 30px -14px rgba(44, 36, 30, .55);
}
/* Scoped past .note p below, which is otherwise more specific than .note-no. */
.note .note-no {
  font: 400 2.15rem/1 var(--display);
  letter-spacing: .06em;
  color: var(--sky);
  margin: 0 0 .3rem;
}
.note h3 {
  font-size: clamp(1.45rem, 2.1vw, 1.85rem);
  margin: 0 0 .7rem;
}
.note p {
  font-size: .95rem;
  color: var(--ink-soft);
  margin: 0;
}

/* --- The pushpin --------------------------------------------------------- */

.pin {
  position: absolute;
  top: -14px; left: 50%;
  width: 28px; height: 28px;
  transform: translateX(-50%);
  pointer-events: none;
}
.pinrow:nth-child(odd)  .pin { --pin: var(--pin-a); }
.pinrow:nth-child(even) .pin { --pin: var(--pin-b); }

/* Drawn first, so it sits behind the head: the collar that reads as the pin
   being pushed in rather than resting on top. */
.pin::before {
  content: "";
  position: absolute;
  left: 50%; top: 58%;
  width: 10px; height: 13px;
  transform: translateX(-50%);
  border-radius: 0 0 4px 4px;
  background: linear-gradient(
    to bottom,
    color-mix(in srgb, var(--pin) 62%, #000),
    color-mix(in srgb, var(--pin) 34%, #000));
}
.pin::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background:
    radial-gradient(circle at 34% 27%, rgba(255, 255, 255, .92), rgba(255, 255, 255, 0) 44%),
    radial-gradient(circle at 70% 80%, rgba(0, 0, 0, .40), rgba(0, 0, 0, 0) 58%),
    var(--pin);
  box-shadow:
    0 5px 9px rgba(44, 36, 30, .38),
    inset 0 -2px 4px rgba(0, 0, 0, .22);
}

/* --- A taped photograph -------------------------------------------------- */

.polaroid {
  position: relative;
  margin: 0;
  justify-self: center;
  width: var(--photo-w, clamp(11rem, 17vw, 14.5rem));
  padding: .7rem .7rem 0;
  background: #fffdf8;
  box-shadow:
    0 2px 3px rgba(44, 36, 30, .16),
    0 18px 32px -16px rgba(44, 36, 30, .55);
}
.polaroid-window {
  aspect-ratio: var(--photo-ar, 1);
  overflow: hidden;
  background: var(--sand-soft);
}
.polaroid-window img { width: 100%; height: 100%; object-fit: cover; }

/* The frame stands empty on purpose until a photograph arrives. The hatch
   says "nothing here yet" in a way a plain grey box does not. */
.polaroid-empty {
  display: grid;
  place-items: center;
  width: 100%; height: 100%;
  color: #cbb79e;
  background:
    repeating-linear-gradient(45deg,
      rgba(216, 199, 178, .34) 0 2px, rgba(216, 199, 178, 0) 2px 10px),
    var(--sand-soft);
}
.polaroid-empty svg { width: 38%; height: auto; }

.polaroid figcaption {
  font: 400 .8rem/1.4 var(--body);
  color: var(--ink-soft);
  text-align: center;
  padding: .8rem .4rem 1rem;
}

/*
   The tape is translucent, so what it should do depends on the board under it.
   On cork it multiplies: tan over tan darkens, which is what tape does.
   On blue it cannot — tan multiplied into Wide Sky turns sage, and a green
   smear appears on a page that has no green in it. There it stays a milky
   cream laid over the top instead, which is how frosted tape reads on a
   cold colour anyway.
*/
.pinboard--sky  { --tape-bg: linear-gradient(158deg, rgba(248, 240, 224, .90), rgba(232, 219, 196, .82)); --tape-blend: normal; }
.pinboard--cork { --tape-bg: linear-gradient(158deg, rgba(224, 200, 162, .82), rgba(196, 168, 127, .72)); --tape-blend: multiply; }

/*
   One print hangs from a clip instead. The string has to read against the
   board behind it, so like the tape it is set per surface: near-white on the
   blue, where a dark thread would vanish into the vignette, and dark on the
   cork, where a pale one would.
*/
.pinboard--sky  { --hang-string: rgba(255, 253, 248, .72); --hang-clip: #2C241E; }
.pinboard--cork { --hang-string: rgba(44, 36, 30, .48);    --hang-clip: #2C241E; }

.tape {
  position: absolute;
  top: -1rem; left: 50%;
  /* A share of the print rather than a fixed length, so one strip of tape
     suits the small square and the wide landscape alike. */
  width: 48%; height: 1.9rem;
  transform: translateX(-50%) rotate(var(--tape-tilt));
  background: var(--tape-bg);
  mix-blend-mode: var(--tape-blend);
  box-shadow: 0 1px 2px rgba(44, 36, 30, .18);
  /* Ends torn rather than cut — a rectangle reads as a sticker, not tape. */
  clip-path: polygon(4% 8%, 13% 0, 42% 5%, 71% 0, 96% 6%, 100% 92%, 74% 100%, 45% 94%, 16% 100%, 0 93%);
}

/*
   The hanging print. Everything that makes it read as hung rather than merely
   tilted is in the pivot: a taped photograph turns about its middle, but one
   on a string turns about the clip holding it, so the whole print swings
   below that point. The margin buys the string its room — without it the
   string is drawn over the note in the row above.
*/
/*
   --hang-drop is how much further down this print hangs. It lengthens the
   string by exactly what it adds to the margin, so however far a print drops,
   the top of its string stays put. That is what lets two of them hang side by
   side at different depths and still read as coming off one rail — give them
   equal strings at different heights instead and the rail appears to bend.
*/
.polaroid--hung {
  --hang-drop: 0rem;
  margin-top: calc(3.1rem + var(--hang-drop));
  transform-origin: top center;
}

.hanger {
  position: absolute;
  top: calc(-3rem - var(--hang-drop)); left: 50%;
  width: 2px; height: calc(3rem + var(--hang-drop));
  transform: translateX(-50%);
  background: var(--hang-string);
}
/*
   The clip straddles the top edge of the print rather than sitting above it,
   which is the whole reason a clip looks like it is carrying any weight.
   The inset highlight along the bottom is its lever catching the light.
*/
.hanger::after {
  content: "";
  position: absolute;
  bottom: -.4rem; left: 50%;
  width: 1.2rem; height: 1.1rem;
  transform: translateX(-50%);
  border-radius: 2px;
  background: var(--hang-clip);
  box-shadow:
    0 1px 3px rgba(44, 36, 30, .4),
    inset 0 -4px 0 rgba(255, 255, 255, .2);
}

/* --- Tilt ---------------------------------------------------------------- */
/*
   [data-reveal].is-visible resets transform to none, which would flatten every
   note on the board the moment it scrolled into view. These carry the same
   reveal but keep their angle, and hold it when motion is turned off.
*/
.note[data-reveal]     { transform: translateY(22px) rotate(var(--note-tilt)); }
.polaroid[data-reveal] { transform: translateY(22px) rotate(var(--photo-tilt)); }
.note[data-reveal].is-visible     { transform: rotate(var(--note-tilt)); }
.polaroid[data-reveal].is-visible { transform: rotate(var(--photo-tilt)); }

@media (prefers-reduced-motion: reduce) {
  .note[data-reveal]     { transform: rotate(var(--note-tilt)); }
  .polaroid[data-reveal] { transform: rotate(var(--photo-tilt)); }
}

/* --- Narrow -------------------------------------------------------------- */

@media (max-width: 860px) {
  /* One column: the note, then its photograph beneath. The trail has nothing
     left to zigzag between, and a tilted full-width card would run off the
     side of the screen, so both go. The photographs keep their three different
     sizes — that reads as a set of prints on a phone just as it does on a
     desktop, and none of them is wide enough here to need reining in. */
  .pinboard .pinrow {
    grid-template-columns: 1fr;
    gap: 2rem;
    --note-tilt: 0deg;
    --photo-tilt: 0deg;
    /* The pair sets its own angles, so straightening the row is not enough. */
    --pair-tilt-a: 0deg;
    --pair-tilt-b: 0deg;
  }
  .pinboard .pinrow .note-slot,
  .pinboard .pinrow .polaroid,
  .pinboard .pinrow .polaroid-pair { grid-column: 1; justify-self: center; }
  .pinboard .pinrow .polaroid,
  .pinboard .pinrow .polaroid-pair { grid-row: auto; }
  .pinboard .pinrow .note { width: min(34rem, 100%); margin-inline: auto; }
  .note-slot { width: 100%; }
  .note-slot::after { content: none; }
}

/* --- Section 4: calendar -------------------------------------------------- */

.cal-layout {
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) minmax(0, .78fr);
  gap: clamp(2rem, 4vw, 3.6rem);
  align-items: start;
}
@media (max-width: 900px) { .cal-layout { grid-template-columns: 1fr; } }

.cal-shell {
  background: rgba(255, 255, 255, .8);
  border: 1px solid var(--sand-line);
  border-radius: var(--radius);
  padding: clamp(1.2rem, 2.6vw, 2.2rem);
}

.cal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 1.4rem;
}
.cal-head h3 { font-size: clamp(1.5rem, 2.6vw, 2.05rem); }
.cal-nav { display: flex; gap: .5rem; }
.cal-nav a, .cal-nav span {
  display: grid; place-items: center;
  width: 42px; height: 42px;
  border: 1px solid var(--sand-line);
  border-radius: 50%;
  text-decoration: none;
  color: var(--ink);
  transition: background-color .3s var(--ease), color .3s var(--ease), border-color .3s var(--ease);
}
.cal-nav a:hover { background: var(--sky); border-color: var(--sky); color: #fff; }
.cal-nav span { opacity: .3; }

.cal-grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 6px; }
.cal-dow {
  text-align: center;
  padding-bottom: .6rem;
  font: 600 .62rem/1 var(--body);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.cal-day {
  position: relative;
  aspect-ratio: 1;
  border-radius: var(--radius-sm);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: .28rem;
  text-decoration: none;
  border: 1px solid transparent;
  font-family: var(--body);
  transition: transform .28s var(--ease), background-color .28s var(--ease),
              color .28s var(--ease), border-color .28s var(--ease);
}
.cal-day .num { font-family: var(--display); font-size: clamp(1rem, 1.8vw, 1.4rem); line-height: 1; }
.cal-day .tag {
  font-size: clamp(.5rem, .74vw, .58rem);
  letter-spacing: .09em;
  text-transform: uppercase;
  font-weight: 600;
  text-align: center;
}

.cal-day--blank { visibility: hidden; }
.cal-day--empty { color: var(--ink-faint); opacity: .45; }
.cal-day--past  { color: var(--ink-faint); opacity: .32; }

.cal-day--taken {
  background: var(--sand);
  color: var(--ink-soft);
  border-color: var(--sand-line);
}
.cal-day--taken .tag { color: #a8543f; }

.cal-day--open {
  background: var(--sky-wash);
  border-color: rgba(0, 157, 201, .38);
  color: var(--sky-deep);
}
.cal-day--open:hover, .cal-day--open:focus-visible {
  background: var(--sky);
  border-color: var(--sky);
  color: #fff;
  transform: translateY(-3px);
}

.cal-legend {
  display: flex;
  flex-wrap: wrap;
  gap: .6rem 1.5rem;
  margin-top: 1.5rem;
  padding-top: 1.3rem;
  border-top: 1px solid var(--sand-line);
  font: 500 .72rem/1 var(--body);
  letter-spacing: .06em;
  color: var(--ink-soft);
}
.cal-legend span { display: inline-flex; align-items: center; gap: .55rem; }
.cal-legend i { width: 13px; height: 13px; border-radius: 4px; border: 1px solid; }
.cal-legend .i-open  { background: var(--sky-wash); border-color: rgba(0, 157, 201, .38); }
.cal-legend .i-taken { background: var(--sand); border-color: var(--sand-line); }

@media (max-width: 520px) {
  .cal-day .tag { display: none; }
  .cal-grid { gap: 4px; }
}

/* --- Section 5: meet Kimi ------------------------------------------------- */

.kimi-grid {
  display: grid;
  grid-template-columns: minmax(0, .82fr) minmax(0, 1.18fr);
  gap: clamp(2.4rem, 5vw, 5rem);
  align-items: center;
}
.kimi-grid .prose { max-width: 54ch; }
.kimi-grid .prose p { color: var(--ink-soft); }
.kimi-grid .prose strong { font-weight: 600; color: var(--ink); }
@media (max-width: 880px) {
  .kimi-grid { grid-template-columns: 1fr; }
  .kimi-portrait { max-width: 400px; }
}

.signature {
  font-family: var(--display);
  font-size: 2rem;
  margin-top: 1.8rem;
  color: var(--sky);
}

/* --- Section 6: what you take home ---------------------------------------- */

.takeaways {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  border: 1px solid var(--sand-line);
  border-radius: var(--radius);
  overflow: hidden;
}
.takeaway {
  position: relative;
  padding: clamp(1.7rem, 3vw, 2.6rem);
  border-right: 1px solid var(--sand-line);
  border-bottom: 1px solid var(--sand-line);
  background: rgba(255, 255, 255, .55);
}
.takeaways > *:nth-child(3n) { border-right: 0; }
.takeaways > *:nth-last-child(-n + 3) { border-bottom: 0; }
.takeaways > *:nth-child(even) { background: rgba(232, 219, 203, .5); }

.takeaway .no {
  position: absolute;
  top: clamp(1.3rem, 2.4vw, 1.9rem);
  right: clamp(1.3rem, 2.4vw, 1.9rem);
  font: 500 .7rem/1 var(--body);
  letter-spacing: .1em;
  color: var(--ink-faint);
}
.takeaway .pill {
  display: inline-block;
  margin-bottom: 1rem;
  padding: .62rem 1.15rem;
  border: 1px solid var(--ink);
  border-radius: 999px;
  font-family: var(--display);
  font-size: 1.12rem;
  line-height: 1.1;
}
.takeaway p { font-size: .93rem; color: var(--ink-soft); }
.takeaway .kind {
  display: block;
  margin-top: .9rem;
  font: 600 .62rem/1 var(--body);
  letter-spacing: .15em;
  text-transform: uppercase;
  color: var(--sky);
}

@media (max-width: 860px) {
  .takeaways { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .takeaways > * { border-right: 1px solid var(--sand-line); border-bottom: 1px solid var(--sand-line); }
  .takeaways > *:nth-child(even) { border-right: 0; }
  .takeaways > *:nth-last-child(-n + 2) { border-bottom: 0; }
}
@media (max-width: 560px) {
  .takeaways { grid-template-columns: 1fr; }
  .takeaway { border-right: 0; border-bottom: 1px solid var(--sand-line); }
  .takeaways > *:last-child { border-bottom: 0; }
}

/* --- Closing band + footer ------------------------------------------------ */

.closer { position: relative; overflow: hidden; text-align: center; }
.closer .k-wash {
  position: absolute; inset: 0;
  background: url("../img/k-tile-white.svg") 0 0 / 150px repeat;
  opacity: .09;
  pointer-events: none;
}
.closer .wrap { position: relative; }
.closer h2 { max-width: 18ch; margin-inline: auto; }
.closer .lede { margin: 1.4rem auto 0; }

.site-footer {
  background: var(--deep);
  color: rgba(255, 255, 255, .66);
  padding-block: clamp(3rem, 6vw, 4.5rem);
  font-size: .88rem;
}
.footer-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 2rem clamp(2rem, 6vw, 5rem);
  justify-content: space-between;
  align-items: flex-start;
}
.footer-grid > div { max-width: 34ch; }
.site-footer .brand svg { height: 26px; width: auto; color: #fff; }
.site-footer h4 {
  font-family: var(--body);
  font-weight: 600;
  font-size: .66rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, .45);
  margin-bottom: .9rem;
}
.site-footer a { color: #fff; text-decoration: none; border-bottom: 1px solid rgba(255, 255, 255, .3); }
.site-footer a:hover { border-color: #fff; }
.footer-note {
  margin-top: 2.6rem;
  padding-top: 1.6rem;
  border-top: 1px solid rgba(255, 255, 255, .14);
  display: flex;
  flex-wrap: wrap;
  gap: .6rem 1.6rem;
  justify-content: space-between;
  font-size: .78rem;
  letter-spacing: .04em;
}

/* --- Booking page ---------------------------------------------------------- */

.booking { padding-top: clamp(132px, 16vw, 195px); }
.booking-grid {
  display: grid;
  grid-template-columns: minmax(0, .85fr) minmax(0, 1.15fr);
  gap: clamp(2.2rem, 5vw, 4.5rem);
  align-items: start;
}
@media (max-width: 880px) { .booking-grid { grid-template-columns: 1fr; } }

.summary {
  background: rgba(255, 255, 255, .7);
  border: 1px solid var(--sand-line);
  border-radius: var(--radius);
  padding: clamp(1.6rem, 3vw, 2.3rem);
}
.summary dl { margin: 0; display: grid; gap: 1.1rem; }
.summary dt {
  font: 600 .64rem/1 var(--body);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-bottom: .35rem;
}
.summary dd { margin: 0; font-family: var(--display); font-size: 1.42rem; line-height: 1.2; }
.summary .includes { margin-top: 1.8rem; padding-top: 1.5rem; border-top: 1px solid var(--sand-line); }
.summary .includes ul { margin: 0; padding: 0; list-style: none; display: grid; gap: .65rem; }
.summary .includes li {
  position: relative;
  padding-left: 1.5rem;
  font-size: .92rem;
  color: var(--ink-soft);
}
.summary .includes li::before {
  content: "";
  position: absolute; left: 0; top: .62em;
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--sky);
}

.form-grid { display: grid; gap: 1.35rem; }
.field { display: grid; gap: .55rem; }
.field > label, .fieldset-label {
  font: 600 .66rem/1 var(--body);
  letter-spacing: .15em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.field input, .field textarea {
  width: 100%;
  padding: .95rem 1.1rem;
  border: 1px solid var(--sand-line);
  border-radius: var(--radius-sm);
  background: rgba(255, 255, 255, .85);
  font: 300 1rem/1.5 var(--body);
  color: var(--ink);
  transition: border-color .3s var(--ease), box-shadow .3s var(--ease);
}
.field input:focus, .field textarea:focus {
  outline: none;
  border-color: var(--sky);
  box-shadow: 0 0 0 3px rgba(0, 157, 201, .14);
}
.field textarea { resize: vertical; min-height: 120px; }
.field .hint { font-size: .8rem; color: var(--ink-faint); }

fieldset { border: 0; margin: 0; padding: 0; display: grid; gap: .8rem; }
.times { display: flex; flex-wrap: wrap; gap: .7rem; }
.time-opt { position: relative; }
.time-opt input { position: absolute; opacity: 0; inset: 0; width: 100%; height: 100%; cursor: pointer; }
.time-opt span {
  display: block;
  padding: .85rem 1.4rem;
  border: 1px solid var(--sand-line);
  border-radius: 999px;
  background: rgba(255, 255, 255, .85);
  font: 500 .92rem/1 var(--body);
  transition: background-color .28s var(--ease), color .28s var(--ease), border-color .28s var(--ease);
}
.time-opt input:checked + span { background: var(--sky); border-color: var(--sky); color: #fff; }
.time-opt input:focus-visible + span { outline: 2px solid var(--sky); outline-offset: 3px; }

.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.notice {
  padding: 1rem 1.25rem;
  border-radius: var(--radius-sm);
  border: 1px solid;
  font-size: .95rem;
  margin-bottom: 1.6rem;
}
.notice--error { background: #fdf2ef; border-color: #e2b7a9; color: #8c3d24; }
.notice--info  { background: var(--sky-wash); border-color: rgba(0, 157, 201, .35); color: var(--sky-deep); }

.confirmation { max-width: 62ch; }
.confirmation .ref {
  display: inline-block;
  margin: 1.6rem 0;
  padding: .9rem 1.6rem;
  border: 1px dashed var(--sky);
  border-radius: var(--radius-sm);
  font: 600 1.15rem/1 var(--body);
  letter-spacing: .16em;
  color: var(--sky-deep);
  background: var(--sky-wash);
}

/* --- Reveal on scroll ------------------------------------------------------ */

[data-reveal] {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity .8s var(--ease), transform .8s var(--ease);
}
[data-reveal].is-visible { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  [data-reveal] { opacity: 1; transform: none; transition: none; }
  .btn:hover, .cal-day--open:hover { transform: none; }
}

/* --- Payment step (booking confirmation) ------------------------------------ */

.pay {
  margin-top: clamp(2.4rem, 5vw, 3.6rem);
  padding: clamp(1.6rem, 3.4vw, 2.8rem);
  background: var(--sand-soft);
  border: 1px solid var(--sand-line);
  border-radius: var(--radius);
}
.pay h2 { font-size: clamp(1.7rem, 3vw, 2.5rem); }
.pay .lede { max-width: 52ch; }
.pay--done { background: var(--sky-wash); border-color: rgba(0, 157, 201, .3); }

.pay-grid {
  display: grid;
  grid-template-columns: minmax(0, .9fr) minmax(0, 1.1fr);
  gap: clamp(1.6rem, 4vw, 3rem);
  margin-top: clamp(1.8rem, 4vw, 2.6rem);
  align-items: start;
}
@media (max-width: 780px) { .pay-grid { grid-template-columns: minmax(0, 1fr); } }

.pay-qr {
  background: #fff;
  border: 1px solid var(--sand-line);
  border-radius: var(--radius-sm);
  padding: clamp(1rem, 2.4vw, 1.5rem);
}
.pay-qr img {
  width: 100%; height: auto; max-width: 320px;
  margin-inline: auto;
  border-radius: 8px;
}
.pay-qr-missing {
  display: grid; gap: 1rem; justify-items: center; text-align: center;
  padding: 2rem 1rem;
}
.pay-qr-missing svg { width: 44px; height: auto; color: var(--sky); }
.pay-qr-missing p { font-size: .92rem; color: var(--ink-soft); }

.pay-account {
  margin: 1.3rem 0 0;
  padding-top: 1.2rem;
  border-top: 1px solid var(--sand-line);
  display: grid; gap: .8rem;
}
.pay-account > div { display: flex; justify-content: space-between; gap: 1rem; align-items: baseline; }
.pay-account dt {
  font: 600 .62rem/1 var(--body);
  letter-spacing: .15em; text-transform: uppercase; color: var(--ink-faint);
}
.pay-account dd {
  margin: 0; font-weight: 500; font-size: .95rem;
  font-variant-numeric: tabular-nums; text-align: right;
}

.pay-upload h3 { font-size: 1.45rem; margin-bottom: .6rem; }
.pay-upload > p { font-size: .95rem; color: var(--ink-soft); max-width: 42ch; }
.pay-upload .form-grid { margin-top: 1.4rem; }
.pay-upload input[type="file"] {
  width: 100%;
  padding: .9rem 1rem;
  border: 1px dashed var(--sand-line);
  border-radius: var(--radius-sm);
  background: #fff;
  font: 400 .92rem var(--body);
  cursor: pointer;
}
.pay-upload input[type="file"]:focus {
  outline: none; border-color: var(--sky); border-style: solid;
  box-shadow: 0 0 0 3px rgba(0, 157, 201, .14);
}
.pay-note {
  margin-top: 1.4rem; font-size: .84rem; color: var(--ink-faint); max-width: 44ch;
}

.pay-again { margin-top: 1.8rem; }
.pay-again summary {
  cursor: pointer;
  font: 500 .82rem/1 var(--body);
  letter-spacing: .06em;
  color: var(--sky-deep);
}
.pay-again[open] summary { margin-bottom: .4rem; }

/* --- "Nothing suits you?" ----------------------------------------------------
   A quiet way out of the calendar, for the person who cannot find a time and
   would otherwise just leave. Deliberately understated: it must not compete
   with the booking button beside it.
   -------------------------------------------------------------------------- */

.contact-prompt {
  margin: 1.1rem 0 0;
  font: 400 .92rem/1.55 var(--body);
  color: var(--ink-soft);
}
.contact-prompt a {
  color: var(--sky-deep);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.contact-prompt a:hover { text-decoration-thickness: 2px; }

/* Inside the time picker it follows the times, so it needs the gap. */
fieldset .contact-prompt { margin-top: .9rem; }

/* --- Deposit or full ---------------------------------------------------------
   Two cards rather than a bare radio pair: the difference between them is
   money and terms, so both have to be readable at a glance, not inferred from
   a label.
   -------------------------------------------------------------------------- */

.pay-opts { display: grid; gap: .7rem; }

.pay-opt {
  display: flex;
  gap: .75rem;
  align-items: flex-start;
  padding: .9rem 1rem;
  border: 1px solid var(--sand-line, #e0d3c2);
  border-radius: 12px;
  background: #fff;
  cursor: pointer;
  transition: border-color .2s ease, box-shadow .2s ease;
}
.pay-opt:hover { border-color: var(--sky-deep); }
.pay-opt:has(input:checked) {
  border-color: var(--sky-deep);
  box-shadow: 0 0 0 1px var(--sky-deep) inset;
}
.pay-opt:has(input:focus-visible) { outline: 2px solid var(--sky-deep); outline-offset: 2px; }
.pay-opt input { margin-top: .25rem; flex: none; }

.pay-opt-body { display: grid; gap: .2rem; min-width: 0; }
.pay-opt-head {
  display: flex;
  flex-wrap: wrap;
  gap: .3rem .6rem;
  align-items: baseline;
  justify-content: space-between;
}
.pay-opt-price { font-weight: 600; color: var(--sky-deep); white-space: nowrap; }
.pay-opt-note { font-size: .86rem; color: var(--ink-soft); }

.pay-terms {
  margin: .6rem 0 0;
  font-size: .86rem;
  color: var(--ink-soft);
}

/* A code that worked should look like it worked. */
.hint--good { color: var(--sky-deep); font-weight: 500; }

/* --- What the session covers -------------------------------------------------
   Seventeen lines, so it gets the full width under the form rather than being
   squeezed into the summary panel, where it would run three times the height
   of the form beside it. Two columns where there is room, one on a phone.
   -------------------------------------------------------------------------- */

.session-covers {
  margin-top: clamp(2.5rem, 6vw, 4rem);
  padding-top: clamp(2rem, 5vw, 3rem);
  border-top: 1px solid var(--sand-line, #e0d3c2);
}
.session-covers h2 {
  margin: 0 0 1.4rem;
  font-family: var(--display);
  font-weight: 400;
  font-size: clamp(1.5rem, 3.2vw, 2.1rem);
  line-height: 1.15;
}

.session-list {
  margin: 0;
  padding: 0;
  list-style: none;
  columns: 2;
  column-gap: 2.5rem;
}
.session-list li {
  /* Keeps a wrapped item from breaking across the column boundary. */
  break-inside: avoid;
  position: relative;
  margin: 0 0 .7rem;
  padding-left: 1.4rem;
  line-height: 1.5;
}
.session-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: .55em;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--sky);
}

.session-gifts-intro {
  margin: 2.2rem 0 1.1rem;
  font-size: 1.02rem;
}
.session-list--gifts li::before { background: var(--sand, #e8dbcb); }

@media (max-width: 720px) {
  .session-list { columns: 1; }
}

/* --- Other ways to pay -------------------------------------------------------
   GCash keeps the QR and the headline treatment because it is the common case.
   The rest are disclosures: present for anyone who needs them, quiet for
   everyone who does not.
   -------------------------------------------------------------------------- */

.pay-others { margin-top: 1.2rem; }
.pay-others-title {
  margin: 0 0 .5rem;
  font: 600 .64rem/1 var(--body);
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.pay-other + .pay-other { margin-top: .4rem; }
.pay-other > summary {
  cursor: pointer;
  padding: .55rem .8rem;
  border: 1px solid var(--sand-line, #e0d3c2);
  border-radius: 8px;
  background: #fff;
  font-weight: 500;
  font-size: .9rem;
  list-style: none;
}
.pay-other > summary::-webkit-details-marker { display: none; }
.pay-other > summary::after { content: " +"; color: var(--sky-deep); }
.pay-other[open] > summary::after { content: " −"; }

.pay-other-body {
  padding: .7rem .8rem 0;
  font-size: .9rem;
  line-height: 1.55;
  color: var(--ink-soft);
}

/* --- Hero sound toggle -------------------------------------------------------
   The hero autoplays muted, because browsers allow nothing else. This is how
   someone asks for the sound. Quiet by default and legible over whatever frame
   happens to be behind it, which is why it carries its own dark plate rather
   than relying on the video being dark.
   -------------------------------------------------------------------------- */

.sound-toggle {
  position: absolute;
  right: .8rem;
  bottom: .8rem;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  padding: .5rem .8rem;
  border: 0;
  border-radius: 999px;
  background: rgba(20, 23, 26, .55);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  color: #fff;
  font: 500 .76rem/1 var(--body);
  cursor: pointer;
  transition: background-color .2s ease, opacity .2s ease;
}
.sound-toggle:hover { background: rgba(20, 23, 26, .78); }
.sound-toggle:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }

.sound-toggle-icons { display: block; width: 17px; height: 17px; }
.sound-toggle-icons svg { width: 17px; height: 17px; display: block; }

/* One icon at a time, chosen by the button's own pressed state so the markup
   stays the single source of truth and JS only flips the attribute. */
.sound-toggle .i-on { display: none; }
.sound-toggle[aria-pressed="true"] .i-on  { display: block; }
.sound-toggle[aria-pressed="true"] .i-off { display: none; }
.sound-toggle[aria-pressed="true"] { background: var(--sky-deep); }
.sound-toggle[aria-pressed="true"]:hover { background: var(--sky); }

/* On a phone the label is the first thing to go; the icon carries it. */
@media (max-width: 520px) {
  .sound-toggle { right: .6rem; bottom: .6rem; padding: .5rem; }
  .sound-toggle-label {
    position: absolute; width: 1px; height: 1px;
    padding: 0; margin: -1px; overflow: hidden;
    clip: rect(0 0 0 0); white-space: nowrap; border: 0;
  }
}

/* A method with a QR says so before you open it, so nobody misses that there
   is something to scan behind a plain-looking name. */
.pay-other-hint {
  margin-left: .35rem;
  padding: .1rem .35rem;
  border-radius: 4px;
  background: var(--sky-wash, #e9f6fb);
  color: var(--sky-deep);
  font-size: .68rem;
  letter-spacing: .04em;
  text-transform: uppercase;
}
/* Written as .pay-qr .pay-other-qr rather than on the class alone: the GCash
   QR above is styled by `.pay-qr img`, which outranks a lone class and would
   otherwise stretch these to the same 320px. A secondary QR should read as
   secondary. */
.pay-qr .pay-other-qr {
  display: block;
  width: 100%;
  max-width: 200px;
  margin: .7rem 0 0;
  border-radius: 8px;
  background: #fff;
}

/* The build credit sits with the copyright line, deliberately quieter than it:
   it belongs to us, not to Kimi's visitors. */
.footer-by { color: rgba(255, 255, 255, .55); }
.footer-by a { color: rgba(255, 255, 255, .8); border-bottom-color: rgba(255, 255, 255, .2); }
.footer-by a:hover { color: #fff; border-bottom-color: #fff; }
