/* ==========================================================================
   trasteli — coming soon

   ACTIVE COLOURWAY: beige, with the logo left white as drawn.

   Colour policy: every value below was sampled straight out of
   logo/Trasteli_beige.png. The page background is that file's own pixels
   (assets/bg.png, a logo-free crop), so the colour and its marbling are the
   originals — not a gradient approximating them. No vignette, no tint, no
   overlay on the field. Nothing recoloured.

   TO SWITCH BACK TO BURGUNDY: copy variants/assets/bg-burgundy.png and
   logo-burgundy.png over assets/bg.png and assets/logo.png, then swap the
   --ground and ink block below for the burgundy values kept in
   variants/burgundy.html. Nothing else changes.

   Polaroid geometry is measured off Landing_page_concept:
     frame aspect 0.831 · square window · side border 6.5% of width
     top border 7.2% · chin 26.05% · fan angles -13° / -1° / +24°
   ========================================================================== */

:root {
  /* sampled from logo/Trasteli_beige.png — do not alter */
  --ground:          #ad9fa4;   /* base, modal colour of the field */

  /* polaroid stock — warm cream, per your call. (The concept photo actually
     samples neutral-cool, #e4e6e5–#f4f6f5; cream sits far better against a
     warm burgundy, so this is a deliberate departure from the reference.) */
  --paper:           #f2ebdd;   /* aged instant-film stock */
  --paper-hi:        #faf5ea;   /* top sheen               */
  --paper-lo:        #e3d9c6;   /* shaded lower edge       */

  /* undeveloped frame — kept dark and warm so the empty windows read as
     unexposed film rather than holes cut in the page */
  --film:            #130a0e;

  /* Burgundy ink: white text on this beige is only 2.5:1. This ground is
     light-mid, so the usable contrast range is compressed — anything under
     ~85% opacity drops below 4.5:1. Opacity therefore can't carry hierarchy
     here; size and weight do. Ratios measured against #ad9fa4. */
  --ink:             #4a1725;              /* 5.74:1 */
  --ink-soft:        #4a1725;              /* 5.74:1 — "coming soon" */
  --ink-mid:         #4a1725;              /* 5.74:1 — fineprint             */
  --ink-placeholder: rgba(74, 23, 37, .90); /* 4.90:1 — "your email"          */
  --ink-faint:       rgba(74, 23, 37, .65); /* 3.10:1 — hairline rules (UI)   */

  /* One polaroid's width — every other dimension derives from it.
     The fan's full visual width (rotated corners included) is 2.69x this, so
     32vw keeps it inside the viewport on a phone; 26vh keeps the whole page on
     one screen on a short laptop. Whichever bites first wins. */
  --pw: clamp(96px, min(32vw, 25vh), 236px);

  --serif: "Hoefler Text", "Baskerville", Palatino, "Palatino Linotype", Georgia, serif;
  --sans:  "Avenir Next", Avenir, "Nunito Sans", "Segoe UI", system-ui, -apple-system, sans-serif;

  --ease: cubic-bezier(.2, .7, .2, 1);
}

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

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

body {
  margin: 0;
  min-height: 100svh;
  display: grid;
  place-items: center;
  /* vertical padding tracks viewport HEIGHT — sizing it in vw lets a short
     window scroll, which is the one thing a coming-soon page shouldn't do */
  padding: clamp(14px, 2.6vh, 38px) clamp(16px, 4vw, 48px);
  overflow-x: hidden;

  /* the exact colour + its own marbling, straight from the logo file */
  background-color: var(--ground);
  background-image: url("assets/bg.png");
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;

  font-family: var(--sans);
  color: var(--ink-soft);
  -webkit-font-smoothing: antialiased;
}

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

.stage {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
  max-width: 900px;
}

/* ---------------------------------------------------------------- the logo */

.mark {
  display: block;
  width: clamp(126px, min(34vw, 22vh), 202px);
  height: auto;
  margin-bottom: clamp(4px, 1.4vh, 16px);
}

/* ------------------------------------------------------------- the polaroids */

.fan {
  display: flex;
  justify-content: center;
  align-items: center;
  /* Room for the rotated corners, which overflow the slot boxes without
     affecting layout. A frame at 24° hangs 0.151×width below its box; add
     the sag on top of that, or the corner lands on "coming soon". */
  padding-block: calc(var(--pw) * .12) calc(var(--pw) * .33);

  /* The corners overhang further right (24°) than left (13°) — 0.079×width
     more — so centring the layout boxes leaves the group visibly off-centre.
     Half that asymmetry as trailing margin pulls the *visual* group to centre. */
  margin-inline-end: calc(var(--pw) * .079);
}

.slot {
  position: relative;
  flex: 0 0 auto;
  width: var(--pw);
  transition: z-index 0s;
}

/* overlap: centre-to-centre spacing measured off the concept
   (left→mid 73.3% of a frame width, mid→right 59.8%) */
.slot--left  { z-index: 1; }
.slot--mid   { z-index: 2; margin-left: calc(var(--pw) * -.267); }
.slot--right { z-index: 3; margin-left: calc(var(--pw) * -.365); }

/* Resting and lifted pose per frame. Angles are the concept's, measured.
   The right frame's sag is eased off the concept's 19% — at full value the
   trio slides downhill and crowds the copy. The tossed-by-hand read survives. */
.slot--left  .polaroid { --rot: -13deg; --sag:  2.0%; --rot-up:  -8deg; --sag-up: -1.4%; }
.slot--mid   .polaroid { --rot:  -1deg; --sag:    0%; --rot-up:   0deg; --sag-up: -3.5%; }
.slot--right .polaroid { --rot:  24deg; --sag:  8.5%; --rot-up:  15deg; --sag-up:  3.0%; }

.polaroid {
  margin: 0;
  width: 100%;
  /* measured: 7.2% top · 6.5% sides · 26.05% chin, all of frame width */
  padding: calc(var(--pw) * .072) calc(var(--pw) * .065) calc(var(--pw) * .2605);

  background-color: var(--paper);
  background-image: linear-gradient(168deg, var(--paper-hi) 0%, var(--paper) 42%, var(--paper-lo) 100%);

  transform: translateY(var(--sag)) rotate(var(--rot));
  transform-origin: 50% 50%;

  box-shadow:
    inset 0 0 0 1px rgba(92, 62, 26, .10),
    0 2px 5px rgba(24, 5, 11, .30),
    0 12px 26px rgba(24, 5, 11, .32);

  transition: transform 460ms var(--ease), box-shadow 460ms var(--ease);
  cursor: pointer;
}

/* pop out: come to the front, straighten a little, enlarge, lift off the field */
.slot:hover, .slot:focus-within, .slot.is-lifted { z-index: 10; }

.slot:hover  .polaroid,
.slot.is-lifted .polaroid,
.polaroid:focus-visible {
  transform: translateY(var(--sag-up)) rotate(var(--rot-up)) scale(1.07);
  box-shadow:
    inset 0 0 0 1px rgba(92, 62, 26, .10),
    0 8px 14px rgba(24, 5, 11, .30),
    0 30px 60px rgba(24, 5, 11, .44);
}

.polaroid:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 5px;
}

/* the square window — undeveloped until a product shot goes in */
.window {
  position: relative;
  aspect-ratio: 1;
  overflow: hidden;
  background-color: var(--film);
  background-image:
    radial-gradient(120% 90% at 28% 10%, rgba(255, 255, 255, .06), transparent 62%),
    linear-gradient(168deg, #1d1116 0%, var(--film) 55%, #170c11 100%);
  box-shadow: inset 0 1px 3px rgba(0, 0, 0, .55);
}

.window img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* The left and right frames share one photo. Mirroring the right one turns an
   obvious repeat into a symmetric pair — dark edges outward, light toward the
   middle — so it reads as deliberate framing of the centre shot. Delete this
   rule once there's a third photograph. */
.slot--right .window img { transform: scaleX(-1); }

/* film grain */
.window::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: .05;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}
.window:has(img)::after { opacity: .03; }

/* ------------------------------------------------------------------- words */

.statement {
  margin: 0;
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(1.05rem, 2.5vw, 1.6rem);
  letter-spacing: .44em;
  text-indent: .44em;          /* balance the trailing tracking */
  color: var(--ink-soft);
}

.contact {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin-top: clamp(18px, 3.4vh, 36px);
  width: 100%;
}

.notify {
  display: flex;
  align-items: baseline;
  gap: 14px;
  width: min(100%, 340px);
  padding-bottom: 9px;
  border-bottom: 1px solid var(--ink-faint);
  transition: border-color 240ms var(--ease);
}
.notify:focus-within { border-bottom-color: var(--ink-soft); }

.notify input {
  flex: 1 1 auto;
  min-width: 0;
  border: 0;
  background: none;
  padding: 0;
  font: 300 .92rem/1.4 var(--sans);
  letter-spacing: .06em;
  color: var(--ink);
}
/* iOS Safari zooms the whole page when a focused input's text is under 16px,
   which crops "notify me" off the right edge. 16px stops it. Scoped to touch
   pointers so the desktop keeps its smaller, more delicate size — and NOT
   fixed with maximum-scale, which would disable pinch-zoom for everyone. */
@media (pointer: coarse) {
  .notify input { font-size: 16px; }
}

.notify input::placeholder { color: var(--ink-placeholder); }
.notify input:focus { outline: none; }
/* Chrome paints an opaque pale-blue background on autofilled fields and it
   can't be overridden by background-color. Deferring the background
   transition effectively forever is the one reliable way to keep the field
   transparent; text-fill-color and caret-color keep the value legible. */
.notify input:-webkit-autofill,
.notify input:-webkit-autofill:hover,
.notify input:-webkit-autofill:focus,
.notify input:-webkit-autofill:active {
  -webkit-text-fill-color: var(--ink);
  caret-color: var(--ink);
  transition: background-color 100000s ease-in-out 0s;
}

.notify button {
  flex: 0 0 auto;
  border: 0;
  background: none;
  padding: 0;
  font: 400 .74rem/1 var(--sans);
  letter-spacing: .18em;
  color: var(--ink-soft);
  cursor: pointer;
  transition: opacity 200ms var(--ease);
}
.notify button:hover { opacity: .68; }
.notify button:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 4px;
}

/* weight 400, not 300: at this size a light weight reads as faint on a light
   ground however good the contrast ratio is */
.status,
.fineprint {
  font-size: .76rem;
  font-weight: 400;
  letter-spacing: .09em;
  text-align: center;
}
/* height is reserved whether or not there's a message, so nothing jumps */
.status    { margin: 10px 0 0; min-height: 1.1em; color: var(--ink-soft); }
.fineprint { margin: 6px 0 0; color: var(--ink-mid); }

/* The signed-up state: the form and its fineprint give way to one line.
   .confirm collapses rather than display:none, so it stays in the
   accessibility tree and gets announced when its text is set. */
.confirm {
  margin: 0;
  max-width: 30ch;
  font-family: var(--serif);
  font-size: clamp(.92rem, 1.9vw, 1.08rem);
  line-height: 1.6;
  letter-spacing: .08em;
  text-align: center;
  color: var(--ink-soft);
  max-height: 0;
  opacity: 0;
  overflow: hidden;
  transition: opacity 460ms var(--ease), max-height 460ms var(--ease);
}

.contact.is-done .confirm { max-height: 8em; opacity: 1; }

.contact.is-done .notify,
.contact.is-done .status,
.contact.is-done .fineprint { display: none; }

/* honeypot — off-screen, never display:none (bots skip those) */
.decoy {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.links {
  margin-top: clamp(20px, 3.4vh, 34px);
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 10px clamp(20px, 4vw, 38px);
}

.ig, .mail {
  display: inline-flex;
  align-items: center;
  gap: .5em;
  font-size: .74rem;
  font-weight: 400;
  letter-spacing: .18em;
  color: var(--ink-soft);
  text-decoration: none;
  padding-bottom: 3px;
  border-bottom: 1px solid var(--ink-faint);
  transition: border-color 240ms var(--ease);
}
/* the two links are a matched pair — same colour, weight and tracking */
.ig:hover, .mail:hover { border-bottom-color: var(--ink-soft); }

.ig:focus-visible, .mail:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 5px;
  border-radius: 1px;
}
.ig__arrow { transition: transform 320ms var(--ease); }
.ig:hover .ig__arrow { transform: translate(2px, -2px); }

/* ------------------------------------------------------------ laying it out */
/* one orchestrated entrance: the logo, then each photo set down in turn */

@media (prefers-reduced-motion: no-preference) {
  .mark, .slot, .statement, .contact { animation: settle 760ms var(--ease) both; }
  .mark            { animation-delay:  60ms; }
  .slot--left      { animation-delay: 300ms; }
  .slot--mid       { animation-delay: 410ms; }
  .slot--right     { animation-delay: 520ms; }
  .statement       { animation-delay: 720ms; }
  .contact         { animation-delay: 830ms; }

  @keyframes settle {
    from { opacity: 0; translate: 0 14px; }
    to   { opacity: 1; translate: 0 0; }
  }
}

@media (prefers-reduced-motion: reduce) {
  .polaroid, .ig__arrow, .notify, .ig { transition: none; }
}

/* --------------------------------------------------------------- small screens */

@media (max-width: 560px) {
  .statement { letter-spacing: .34em; text-indent: .34em; }
  .notify { width: 100%; }
}

/* a window squashed very short — claw back the gaps before resorting to scroll */
@media (max-height: 560px) {
  .fan      { padding-block: calc(var(--pw) * .10) calc(var(--pw) * .28); }
  .contact  { margin-top: 12px; }
  .status   { margin-top: 6px; }
  .ig       { margin-top: 14px; }
}
