/* =========================================================================
   Faint Object - styles.css
   -------------------------------------------------------------------------
   Plain-English guide for editing (no coding needed):
   • COLOURS, FONTS and SPACING all live in the ":root" block just below.
     Change a value there once and it updates everywhere on the site.
   • Everything is built from four colours only: white paper, charcoal ink,
     one blue accent, and a rare gold. If the page ever looks colourful,
     something has been changed by mistake.
   ========================================================================= */

/* -------------------------------------------------------------------------
   1. DESIGN TOKENS  (the brand system - edit values here)
   ------------------------------------------------------------------------- */
:root {
  /* --- Palette (exact brand hexes) --- */
  --paper:     #FFFFFF;   /* dominant background - the site is mostly white  */
  --ink:       #3C3C3D;   /* primary text - soft charcoal, not pure black    */
  --blue:      #4C84FC;   /* the "star" accent - logo star, focus rings      */
  --blue-text: #2C57CE;   /* darker blue used only for small text/links (AA) */
  --gold:      #E5C123;   /* rare second accent - a whisper, never a fill    */
  --error:     #B23B2E;   /* form validation messages only                   */

  /* --- Supporting neutrals (derived from ink; keep subtle) --- */
  --ink-60:    #6f6f70;   /* muted text (sub-lines, captions)                */
  --hairline:  #e7e7e7;   /* faint dividers / input borders                  */

  /* --- Type families (Hina Mincho for everything) --- */
  --font-display: "Hina Mincho", Georgia, "Times New Roman", serif;
  --font-body:    "Hina Mincho", Georgia, "Times New Roman", serif;

  /* --- Fluid type scale (grows with the screen via clamp) --- */
  --step-hero:  clamp(2.5rem, 6vw, 6rem);      /* the hero slogan            */
  --step-h2:    clamp(1.75rem, 3vw, 3rem);     /* section headings           */
  --step-h3:    clamp(1.15rem, 1.6vw, 1.4rem); /* small headings / row items */
  --step-body:  1.125rem;                       /* body copy                  */
  --step-small: 0.9375rem;                      /* labels, nav, captions      */

  /* --- Spacing / vertical rhythm (sections breathe - lots of negative space) --- */
  --section-y:  clamp(6rem, 14vw, 13rem);      /* top/bottom padding of sections */
  --gap:        clamp(1rem, 2.5vw, 2rem);
  --measure:    62ch;                           /* max reading width          */
  --pad-x:      clamp(1rem, 2.4vw, 1.9rem);     /* SMALL side gutter - content sits tight to the edges */
  --container-max: 1640px;                       /* only caps on very wide screens */
  --frame-pad:  15px;                            /* header/footer edge padding = the space around the logo */

  --line-tight:  1.05;
  --line-normal: 1.6;

  --header-h:   54px;
}

/* -------------------------------------------------------------------------
   2. RESET / BASE
   ------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }

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

body {
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--step-body);
  line-height: var(--line-normal);
  font-weight: 400;
  letter-spacing: 0.05em;               /* base tracking so body/prose text is spaced too */
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

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

a { color: var(--blue-text); text-decoration: none; }
a:hover { color: var(--blue); }

h1, h2, h3 { font-family: var(--font-display); font-weight: 400; line-height: var(--line-tight); letter-spacing: -0.015em; }

/* Shared layout helpers - full width with a small gutter, tight to the edges */
.container { width: 100%; max-width: var(--container-max); margin-inline: auto; padding-inline: var(--pad-x); }
.measure   { max-width: var(--measure); }

/* Accessible-but-invisible (for skip link, honeypot labels, screen-reader text) */
.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%);
  white-space: nowrap; border: 0;
}

/* Visible focus ring everywhere (accessibility) */
:focus-visible { outline: 2px solid var(--blue); outline-offset: 3px; border-radius: 2px; }

/* Skip link */
.skip-link {
  position: absolute; left: 1rem; top: -3rem;
  background: var(--ink); color: var(--paper);
  padding: 0.5rem 0.9rem; border-radius: 4px; z-index: 100;
  transition: top 0.2s ease;
}
.skip-link:focus { top: 1rem; color: var(--paper); }

/* The brand star - a small reusable mark */
.star {
  display: inline-block;
  width: 1em; height: 1em;
  color: var(--blue);
  vertical-align: -0.08em;
}
.star svg { width: 100%; height: 100%; }

/* -------------------------------------------------------------------------
   3. HEADER (sticky, minimal - transparent over hero, white on scroll)
   ------------------------------------------------------------------------- */
.site-header {
  /* Absolute (not static) so it overlays the top and reserves NO flow space -
     this lets the hero begin at the very top and its sticky pin lock from the
     first pixel of scroll. It still scrolls away with the page. */
  position: absolute; top: 0; left: 0; right: 0; z-index: 50;
  height: var(--header-h);
  display: flex; align-items: center;
  padding-inline: var(--frame-pad);              /* side padding = the space around the logo */
  background: transparent;
}
/* Header content spans the full window width (not the centred container) */
.site-header .container {
  max-width: none; padding-inline: 0;
  display: flex; align-items: center; justify-content: space-between;
}

/* The logo mark - charcoal throughout (the hero is a light/paper field). */
.brand { display: inline-flex; align-items: center; line-height: 0; }
.brand-logo { height: 24px; width: auto; }

.nav-enquire {
  font-family: var(--font-body); font-weight: 700; font-size: var(--step-small);
  text-transform: uppercase; letter-spacing: 0.18em; color: var(--ink);
  padding: 0.5rem 0.2rem; position: relative;
  transition: color 0.3s ease;
}
.nav-enquire::after {
  content: ""; position: absolute; left: 0; right: 100%; bottom: 0.2rem;
  height: 1px; background: var(--blue); transition: right 0.3s ease;
}
.nav-enquire:hover::after { right: 0; }

/* -------------------------------------------------------------------------
   4. HERO  (type-led "apparent emptiness" on paper - mostly negative space)
   ------------------------------------------------------------------------- */
/* Scroll distance for the reveal: the taller the track, the slower the growth. */
.hero {
  position: relative;
  height: 300vh;                                   /* = ~200vh of pinned growth */
  background: var(--paper);
  --star-size: clamp(14px, 2.5vmin, 24px);           /* small at rest; JS grows it on scroll */
  --star-pos: 72% 30%;                             /* JS pins this so it grows FROM the top-right */
  --tint-op: 1;
  --slogan-op: 1;
  --cue-op: 1;
}
.hero__pin {
  position: sticky; top: 0;
  height: 100dvh; overflow: hidden;   /* dvh fills the viewport as iOS's address bar hides */
  background: var(--paper);
}

/* The star window: the image, masked to the star shape, with a blue tint that
   fades as the star opens. The star sits in the top-right third and grows from
   there. Both layers share the growing --star-size mask. */
.hero__reveal {
  position: absolute; inset: 0;
  -webkit-mask: url("assets/logo/star-mask.svg") no-repeat var(--star-pos) / var(--star-size);
          mask: url("assets/logo/star-mask.svg") no-repeat var(--star-pos) / var(--star-size);
  -webkit-mask-mode: alpha; mask-mode: alpha;
  filter: drop-shadow(0 0 44px rgba(76,132,252,0.20));  /* faint aura while small */
  will-change: -webkit-mask-size, mask-size;
}
.hero__img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: center 45%; }
.hero__tint { position: absolute; inset: 0; background: var(--blue); opacity: var(--tint-op); }

.hero__inner {
  position: absolute;
  left: clamp(1.25rem, 17vw, 330px); right: var(--pad-x);   /* indented in from the left */
  top: 56%; bottom: auto;                                   /* sits around the vertical middle */
  /* Centre offset (-50%) plus the scroll-driven shift, so the text scrolls up
     away with the page instead of staying pinned. */
  transform: translateY(calc(-50% - var(--hero-shift, 0px)));
  opacity: var(--slogan-op); pointer-events: none;
  will-change: transform;
}
.hero__slogan {
  font-size: clamp(2.1rem, 5.2vw, 4rem);
  font-weight: 400;
  line-height: 1.06;
  font-optical-sizing: auto;
  letter-spacing: -0.03em;
  color: var(--ink);
  max-width: none;
  white-space: nowrap;                            /* "Visuals for the unbuilt" stays on one line */
  text-wrap: balance;
}
/* Sub-line under the hero slogan - smaller, quieter, kept to a single line. */
.hero__sub {
  margin-top: clamp(0.9rem, 1.6vw, 1.4rem);
  font-size: clamp(0.82rem, 1.25vw, 1.15rem);
  line-height: 1.35;
  color: var(--ink-60);
  white-space: nowrap;
}

.scroll-cue {
  /* Fixed in place at the bottom of the pinned hero (above the fold) - it stays
     put and only fades as you scroll, rather than riding up the page. */
  position: absolute; left: var(--pad-x); bottom: clamp(1.5rem, 3vh, 2.5rem);
  font-size: 1.25rem; color: var(--ink-60);
  opacity: var(--cue-op);
}
.scroll-cue .arrow { display: inline-block; animation: nudge 2.4s ease-in-out infinite; }
@keyframes nudge { 0%,100% { transform: translateY(0); } 50% { transform: translateY(5px); } }

/* Reduced motion: no pinned scroll effect. Show a calm static hero - the small
   blue star + the slogan - with no growth or image reveal. */
@media (prefers-reduced-motion: reduce) {
  .hero { height: auto; }
  .hero__pin { position: static; min-height: 100svh; display: grid; align-items: end; }
  .hero__reveal { --star-size: clamp(14px, 2.5vmin, 24px); }
  .hero__tint { opacity: 1; }              /* keep it a blue star, not an image */
  .scroll-cue .arrow { animation: none; }
}

/* -------------------------------------------------------------------------
   5. SECTIONS (shared editorial rhythm)
   ------------------------------------------------------------------------- */
.section { padding-block: var(--section-y); }
.section--tight { padding-block: clamp(3rem, 6vw, 5rem); }

.eyebrow {
  font-family: var(--font-body); font-weight: 500;
  font-size: var(--step-small); letter-spacing: 0.21em; text-transform: uppercase;
  color: var(--ink-60); margin-bottom: 1.25rem;
  display: inline-flex; align-items: center; gap: 0.6rem;
}
.section h2 { font-size: var(--step-h2); font-weight: 400; max-width: 18ch; }
.section .lede { margin-top: 1.25rem; font-size: clamp(1.15rem, 1.6vw, 1.4rem); color: var(--ink); }
.section p + p { margin-top: 1.1rem; }
.prose { font-size: var(--step-body); color: var(--ink); }
.prose p { max-width: var(--measure); }
/* Section 3 "what we do" copy runs a size larger than default body prose. */
#what-we-do .prose { font-size: clamp(1.3rem, 1.9vw, 1.6rem); line-height: 1.45; }

/* --- Section 4: deliverables - what comes out of one production --- */
#del-h { max-width: none; white-space: nowrap; }   /* keep the heading on one line */
.deliverables {
  list-style: none; padding: 0;
  margin-top: clamp(2rem, 5vw, 3.5rem);
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: clamp(1.75rem, 3.2vw, 3rem) clamp(1.5rem, 3vw, 3rem);
}
.deliverables li { border-top: 1px solid var(--hairline); padding-top: clamp(0.9rem, 1.4vw, 1.2rem); }
.deliverables h3 { font-size: var(--step-h3); margin-bottom: 0.45rem; }
.deliverables p { font-size: var(--step-small); color: var(--ink-60); max-width: 30ch; }
@media (min-width: 641px) and (max-width: 1040px) { .deliverables { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 640px) { .deliverables { grid-template-columns: 1fr; gap: 1.25rem; } }

/* A faint full-width hairline used as an optional section divider */
.rule { border: 0; border-top: 1px solid var(--hairline); }

/* Placeholder note styling (removed as sections are filled) */
.stub {
  margin-top: 1.5rem; padding: 1.25rem 1.5rem;
  border: 1px dashed var(--hairline); border-radius: 6px;
  color: var(--ink-60); font-size: var(--step-small);
  max-width: var(--measure);
}

/* --- Section 2: the "faint object" idea (emotional core, serif, spacious) --- */
.idea .eyebrow em { font-style: italic; }
.idea__body {
  margin-top: clamp(1.5rem, 4vw, 2.5rem);
  font-family: var(--font-display);
  font-size: clamp(1.5rem, 3.2vw, 2.6rem);
  line-height: 1.3;
  letter-spacing: -0.015em;
  max-width: 24ch;
  color: var(--ink);
}
.idea__body p + p { margin-top: 1.4rem; }
@media (min-width: 800px) { .idea__body { max-width: 28ch; } }

/* --- Section 3: the Stills · Films · The method row --- */
.triple {
  list-style: none; padding: 0;
  margin-top: clamp(2.5rem, 6vw, 4.5rem);
  display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(1.5rem, 4vw, 3rem);
  border-top: 1px solid var(--hairline); padding-top: clamp(2rem, 4vw, 3rem);
}
.triple h3 { font-size: var(--step-h3); margin-bottom: 0.6rem; }
.triple p { font-size: var(--step-small); color: var(--ink-60); max-width: 34ch; }
@media (max-width: 720px) { .triple { grid-template-columns: 1fr; gap: 1.75rem; } }

/* --- Section 4: problem / what-changes + frictions --- */
.problem-grid {
  margin-top: clamp(2.5rem, 5vw, 4rem);
  display: grid; grid-template-columns: 1fr 1fr; gap: clamp(2rem, 5vw, 4rem);
}
.problem-block p:not(.block-label) { max-width: 46ch; color: var(--ink); }
.block-label {
  font-family: var(--font-body); font-weight: 500; font-size: var(--step-small);
  letter-spacing: 0.18em; text-transform: uppercase; color: var(--blue-text);
  margin-bottom: 0.9rem;
}
@media (max-width: 720px) { .problem-grid { grid-template-columns: 1fr; gap: 2rem; } }

.frictions {
  list-style: none; padding: 0;
  margin-top: clamp(2.5rem, 5vw, 4rem);
  display: grid; grid-template-columns: 1fr 1fr; gap: 0;
  max-width: 62rem;
}
.frictions li {
  padding: 1.1rem 0; border-top: 1px solid var(--hairline);
  font-size: 1.0625rem; color: var(--ink); padding-right: 2rem;
}
@media (max-width: 620px) { .frictions { grid-template-columns: 1fr; } }

/* --- Section 5: portfolio carousel (pinned; page-scroll slides it sideways) ---
   The section itself has no default section padding here - the tall .work__track
   provides the scroll distance, and .work__pin sticks for one viewport while
   script.js translates .work-grid horizontally. No manual drag/scroll. */
.work { padding-block: 0; }
.work__track { position: relative; height: 320vh; }   /* taller = slower sideways slide */
.work__pin {
  position: sticky; top: 0;
  height: 100svh;
  display: flex; flex-direction: column; justify-content: center;
  gap: clamp(1.5rem, 4vw, 3rem);
  overflow: hidden;                    /* clip the off-screen cards; kills drag-scroll */
}

.work-grid {
  display: flex; gap: clamp(1rem, 2vw, 1.75rem);
  width: max-content;                  /* row is as wide as its cards */
  /* Start the first card's left edge in line with the "Selected work" heading
     (i.e. the .container's content edge), while the row itself stays full-bleed. */
  padding-left: max(var(--pad-x), calc((100% - var(--container-max)) / 2 + var(--pad-x)));
  padding-right: clamp(4rem, 12vw, 12rem);  /* breathing room past the last card */
  will-change: transform;
}

.work-item { margin: 0; flex: 0 0 clamp(300px, 32vw, 460px); }
.work-item__media {
  position: relative; overflow: hidden; background: #f0f0f0;
  aspect-ratio: 3 / 4;                 /* uniform cards; portrait sources crop gently */
}
.work-item__media img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.6s cubic-bezier(.2,.6,.2,1); }
/* Hover: gentle zoom (desktop pointers only) */
@media (hover: hover) {
  .work-item:hover .work-item__media img { transform: scale(1.04); }
}

/* Reduced motion / no-JS fallback: don't pin or scroll-jack - lay the row out
   as an ordinary side-scrollable strip the user can swipe. */
@media (prefers-reduced-motion: reduce) {
  .work__track { height: auto; }
  .work__pin {
    position: static; height: auto; overflow-x: auto; overflow-y: hidden;
    justify-content: flex-start;
  }
  .work-grid { transform: none !important; }
}

/* --- Section 6: the enquiry form (minimal, underline-style) --- */
.enquiry { margin-top: clamp(2.5rem, 5vw, 4rem); max-width: 46rem; }

/* Honeypot - off-screen but still in the DOM for bots to trip on */
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(1.25rem, 3vw, 2.25rem); }
@media (max-width: 620px) { .field-row { grid-template-columns: 1fr; gap: 0; } }

.field { display: flex; flex-direction: column; margin-bottom: clamp(1.5rem, 3vw, 2rem); }
.field label {
  font-family: var(--font-body); font-weight: 500; font-size: 1.15rem;
  letter-spacing: 0.05em; color: var(--ink-60); margin-bottom: 0.5rem;
}
.field input, .field select, .field textarea {
  font-family: var(--font-body); font-size: 1.0625rem; color: var(--ink);
  background: transparent; border: 0; border-bottom: 1px solid var(--hairline);
  padding: 0.7rem 0; min-height: 44px;                 /* big tap targets */
  border-radius: 0; transition: border-color 0.2s ease;
}
.field textarea { resize: vertical; line-height: 1.5; min-height: 3.4rem; }
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none; border-bottom-color: var(--blue); box-shadow: 0 1px 0 0 var(--blue);
}
.field select {
  appearance: none; -webkit-appearance: none; cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='none' stroke='%236f6f70' stroke-width='1.5' d='M1 1.5 6 6.5 11 1.5'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 0.2rem center; padding-right: 1.6rem;
}
.field.invalid input, .field.invalid select, .field.invalid textarea { border-bottom-color: var(--error); }
.field-error { color: var(--error); font-size: var(--step-small); margin-top: 0.4rem; min-height: 0; }

.btn-submit {
  margin-top: 0.5rem; align-self: flex-start;
  font-family: var(--font-body); font-weight: 500; font-size: 1rem;
  text-transform: uppercase; letter-spacing: 0.18em;
  color: var(--ink); background: transparent;
  border: 1px solid var(--ink); border-radius: 100px;
  padding: 0.85rem 1.9rem; min-height: 48px; cursor: pointer;
  transition: background-color 0.25s ease, color 0.25s ease, border-color 0.25s ease;
}
.btn-submit:hover { background: var(--ink); color: var(--paper); }
.btn-submit:disabled { opacity: 0.5; cursor: default; }
.btn-submit:disabled:hover { background: transparent; color: var(--ink); }

.form-status { margin-top: 1.25rem; font-size: var(--step-small); min-height: 1.2em; }
.form-status.is-error { color: var(--error); }

.form-success { margin-top: clamp(2.5rem, 5vw, 4rem); max-width: var(--measure); }
.form-success p { font-family: var(--font-display); font-size: clamp(1.4rem, 2.6vw, 2.1rem); line-height: 1.3; color: var(--ink); }

/* --- Enquiry quiz (stepped, one question at a time) --- */
.quiz { margin-top: clamp(2.5rem, 5vw, 4rem); max-width: 46rem; }
.quiz__progress { margin-bottom: clamp(1.75rem, 4vw, 2.75rem); }
.quiz__bar { height: 2px; background: rgba(255,255,255,0.18); border-radius: 2px; overflow: hidden; }
.quiz__bar span { display: block; height: 100%; width: 10%; background: var(--paper); transition: width 0.35s cubic-bezier(.2,.6,.2,1); }
.quiz__count { margin-top: 0.6rem; font-size: var(--step-small); letter-spacing: 0.15em; text-transform: uppercase; color: rgba(255,255,255,0.5); }

.quiz-step { border: 0; padding: 0; margin: 0; min-inline-size: 0; }
.quiz-step legend {
  display: block;
  font-family: var(--font-display); font-weight: 400;
  font-size: clamp(1.4rem, 2.8vw, 2.2rem); line-height: 1.16; letter-spacing: 0.05em;
  color: var(--paper); padding: 0; margin-bottom: clamp(1.5rem, 3vw, 2.25rem);
  white-space: nowrap;                             /* question stays on one line */
}

.options { display: grid; gap: 0.7rem; }
.option {
  position: relative; display: block; cursor: pointer;
  border: 1px solid rgba(255,255,255,0.22); border-radius: 10px;
  padding: 0.95rem 1.15rem;
  transition: border-color 0.2s ease, background-color 0.2s ease;
}
.option:hover { border-color: rgba(255,255,255,0.5); }
.option input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.option__t { display: block; font-size: 1.0625rem; color: var(--paper); }
.option__d { display: block; margin-top: 0.2rem; font-size: var(--step-small); color: rgba(255,255,255,0.5); }
.option.is-selected { border-color: var(--paper); background: rgba(255,255,255,0.07); }
/* No blue focus ring on the option cards. iOS reports :focus-visible on a plain
   tap (and the first radio is focused when the form opens), which was drawing the
   blue outline on open/select. Selection is shown by .is-selected instead. */
.option:focus-within { outline: none; }
.option:has(input:focus-visible) { outline: none; }
.option input:focus, .option input:focus-visible { outline: none; }

.quiz-error { color: #ff8f82; font-size: var(--step-small); margin-top: 0.85rem; min-height: 1.2em; }

.quiz__nav { display: flex; align-items: center; gap: 1.25rem; margin-top: clamp(1.75rem, 4vw, 2.75rem); }
.btn-back {
  font-family: var(--font-body); font-size: var(--step-small); letter-spacing: 0.09em;
  color: rgba(255,255,255,0.65); background: transparent; border: 0; cursor: pointer;
  padding: 0.5rem 0.2rem; transition: color 0.2s ease;
}
.btn-back:hover { color: var(--paper); }
@media (max-width: 620px) { .quiz-step .field-row { grid-template-columns: 1fr; gap: 0; } }

/* Suite coda line (Section 3) */
.suite-coda {
  margin-top: clamp(2.25rem, 4vw, 3.25rem);
  font-size: clamp(1.15rem, 1.6vw, 1.4rem); line-height: 1.4;
  color: var(--ink); max-width: 48ch;
}

/* --- Inverted section (charcoal ground, light text) - used by the enquiry --- */
.section--invert { background: var(--ink); color: var(--paper); }
.section--invert .eyebrow { color: rgba(255,255,255,0.55); }
.section--invert h2,
.section--invert .lede,
.section--invert .form-success p { color: var(--paper); }
.section--invert .field label { color: rgba(255,255,255,0.62); }
.section--invert .field input,
.section--invert .field select,
.section--invert .field textarea {
  color: var(--paper); border-bottom-color: rgba(255,255,255,0.28);
}
.section--invert .field input::placeholder,
.section--invert .field textarea::placeholder { color: rgba(255,255,255,0.4); }
.section--invert .field input:focus,
.section--invert .field select:focus,
.section--invert .field textarea:focus { border-bottom-color: var(--blue); box-shadow: 0 1px 0 0 var(--blue); }
/* light caret for the selects */
.section--invert .field select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='none' stroke='%23ffffff' stroke-opacity='0.7' stroke-width='1.5' d='M1 1.5 6 6.5 11 1.5'/%3E%3C/svg%3E");
}
/* the native dropdown menu renders on a light background - keep its text dark */
.section--invert .field select option { color: #1a1a1a; background: #fff; }
.section--invert .field.invalid input,
.section--invert .field.invalid select,
.section--invert .field.invalid textarea { border-bottom-color: #ff8f82; }
.section--invert .field-error,
.section--invert .form-status.is-error { color: #ff8f82; }
.section--invert .btn-submit { color: var(--paper); border-color: var(--paper); }
.section--invert .btn-submit:hover { background: var(--paper); color: var(--ink); }
.section--invert .btn-submit:disabled:hover { background: transparent; color: var(--paper); }

/* --- Enquiry as its own full-screen page (a scroll-locked overlay) --- */
.enquire-overlay {
  /* Full layout viewport, always. The visual viewport (keyboard open, page
     panned) can only move within the layout viewport, so a full-height fixed
     overlay can never expose the page behind - no JS sizing required. */
  position: fixed; top: 0; left: 0; right: 0; height: 100dvh; z-index: 300;
  display: flex;                                     /* child margin:auto centres it and
                                                        stays scrollable if a step is tall */
  overflow-y: auto; overflow-x: hidden; overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  padding-block: clamp(0.75rem, 2vh, 1.75rem);
}
/* When the keyboard is up, flow the step from the top and let it scroll rather
   than vertically centring it (centring hides it behind the keyboard).
   ID selector so it beats the mobile `#enquire { align-items: center }` rule. */
#enquire.kb-open { align-items: flex-start; min-height: 0; }  /* min-height:0 lets the JS visualViewport height apply */
#enquire.kb-open .container { margin-block: 0; }
.enquire-overlay .container { margin: auto; }
.enquire-overlay #enq-h { font-size: clamp(1.15rem, 2.4vw, 1.6rem); margin-bottom: 0.5rem; }
.enquire-overlay .lede { display: none; }           /* keep the focused form compact */
#enquire[hidden] { display: none; }   /* id beats the mobile #enquire display rule */
/* Compact the overlay on larger screens so the tallest (6-option) step fits the
   window without needing to scroll. */
@media (min-width: 641px) {
  .enquire-overlay .quiz { margin-top: clamp(1rem, 2.5vh, 1.75rem); }
  .enquire-overlay .quiz__progress { margin-bottom: clamp(0.9rem, 2vh, 1.4rem); }
  .enquire-overlay .quiz-step legend { font-size: clamp(1.3rem, 2.2vw, 1.85rem); margin-bottom: clamp(0.85rem, 2vh, 1.35rem); }
  .enquire-overlay .options { gap: 0.5rem; }
  .enquire-overlay .option { padding: 0.6rem 1rem; }
  .enquire-overlay .quiz__nav { margin-top: clamp(0.9rem, 2.5vh, 1.6rem); }
}
.enquire-close {
  position: fixed; top: clamp(0.6rem, 3vw, 1.5rem); right: clamp(0.6rem, 3vw, 1.5rem);
  z-index: 310; width: 44px; height: 44px; padding: 0;
  border: 0; background: transparent; color: var(--paper);
  font-size: 2rem; line-height: 1; cursor: pointer; opacity: 0.65;
  transition: opacity 0.2s ease;
}
.enquire-close:hover { opacity: 1; }
/* Real iOS-safe scroll lock: freeze the page behind (script.js sets top:-scrollY)
   so the keyboard can't scroll the home page into view under the overlay.
   The background override repaints the whole canvas (body bg propagates to it)
   in the overlay's dark, so even if iOS pans the visual viewport past the
   overlay's edge while the keyboard is up, the sliver it exposes is dark -
   never the white page. */
body.enquiry-open { position: fixed; left: 0; right: 0; width: 100%; overflow: hidden; background: var(--ink); }

/* "Tell us about your project" stays on one line on desktop */
#enq-h { max-width: none; white-space: nowrap; }
@media (max-width: 640px) { #enq-h { white-space: normal; } }

/* -------------------------------------------------------------------------
   6. MOTION PREFERENCES
   ------------------------------------------------------------------------- */
/* Elements that fade/rise in on scroll start hidden, then get .is-visible from JS */
.reveal { opacity: 0; transform: translateY(16px); transition: opacity 0.55s ease, transform 0.55s ease; }
.reveal.is-visible { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .reveal { opacity: 1 !important; transform: none !important; transition: none !important; }
  .scroll-cue .arrow { animation: none; }
  .hero__star { animation: none; }
}

/* -------------------------------------------------------------------------
   7. FOOTER
   ------------------------------------------------------------------------- */
/* Inverted footer: charcoal ground, light text, spanning the full window */
.site-footer {
  background: var(--ink); color: var(--paper);
  padding: clamp(3rem, 7vw, 5rem);                     /* equal padding on all four sides */
  border-top: 1px solid rgba(255,255,255,0.12);
}
/* Start a project (left) · logo (centred) · meta (right) */
.site-footer .container {
  max-width: none; padding-inline: 0;
  display: grid; grid-template-columns: 1fr auto 1fr;
  align-items: center; gap: 1.5rem 2rem;
}
.footer-start { justify-self: start; }
.footer-logo  { justify-self: center; height: 64px; width: auto; }
.footer-meta  { justify-self: end; }
@media (max-width: 860px) {
  .site-footer .container { grid-template-columns: 1fr; justify-items: center; text-align: center; }
  .footer-start, .footer-logo, .footer-meta { justify-self: center; }
  .footer-meta { justify-content: center; }
  .footer-logo { height: 54px; }
}
.footer-start { font-family: var(--font-display); font-size: var(--step-h3); color: var(--paper); }
.footer-start:hover { color: var(--paper); }
.footer-start .arrow { color: var(--blue); }
.footer-meta { display: inline-flex; align-items: center; gap: 1.5rem; flex-wrap: wrap; }
.footer-social { font-family: var(--font-body); font-size: var(--step-small); letter-spacing: 0.03em; color: var(--paper); }
.footer-social:hover { color: var(--blue); }
.footer-legal { font-size: var(--step-small); color: rgba(255,255,255,0.55); display: inline-flex; align-items: center; gap: 0.6rem; }
.footer-legal .star { width: 0.8em; height: 0.8em; }

/* -------------------------------------------------------------------------
   8. RESPONSIVE
   ------------------------------------------------------------------------- */
@media (max-width: 640px) {
  .hero__slogan { max-width: 100%; white-space: normal; }   /* wraps on small screens */
}
/* One line on wide desktop; wrap below that so the longer sub-line never
   overflows (the extra letter-spacing needs more width to stay one line). */
@media (max-width: 1100px) {
  .hero__sub { white-space: normal; }
}

/* ===== MOBILE (phones) - larger type, repositioned hero, form that fits ===== */
@media (max-width: 640px) {
  /* Everything 25% bigger */
  html { font-size: 125%; }

  /* …but the header nav (INSTAGRAM / ENQUIRE) 25% smaller than its normal size.
     Scoped to .site-header so it out-specifies the redesign's .nav-ig rule. */
  .site-header .nav-ig, .site-header .nav-enquire { font-size: calc(var(--step-small) * 0.75); }

  /* More breathing room either side of the centred home copy on phones. */
  .home-copy .container { padding-inline: clamp(1.75rem, 8vw, 3rem); }
  .home-deliverables { padding-inline: clamp(1.75rem, 8vw, 3rem); }
  .site-footer-min { padding-inline: clamp(1.75rem, 8vw, 3rem); }

  /* Lighter, cheaper shadow so 24 orbiting images stay smooth on touch GPUs.
     Scoped to .ring so it out-specifies the base .ring-item shadow. */
  .ring .ring-item { box-shadow: 0 10px 26px rgba(30, 30, 32, 0.24); }

  /* Hero: left edge in line with the fO logo, sitting in the bottom quarter,
     still riding up with the scroll. */
  .hero__inner {
    left: var(--frame-pad); right: var(--frame-pad);
    top: auto; bottom: 15vh;
    transform: translateY(calc(-1 * var(--hero-shift, 0px)));
  }

  /* Deliverables heading matches "Selected work" size on mobile (may wrap). */
  #del-h { font-size: var(--step-h2); max-width: 18ch; white-space: normal; }

  /* Belt-and-braces: stop the wide work carousel from letting the page pan
     sideways on touch browsers (iOS can pan even a clipped wide element). */
  html, body { overflow-x: clip; }

  /* Enquiry: fit a single quiz step within the window height, no scroll needed */
  #enquire {
    min-height: 100svh; display: flex; align-items: center;
    padding-block: clamp(0.75rem, 2vh, 1.5rem);
  }
  #enquire .container { width: 100%; }
  #enquire h2 { font-size: clamp(1.15rem, 5vw, 1.5rem); }
  #enquire .lede { margin-top: 0.4rem; font-size: 0.85rem; }
  .quiz { margin-top: clamp(0.75rem, 2.5vh, 1.4rem); }
  .quiz__progress { margin-bottom: clamp(0.7rem, 2vh, 1.2rem); }
  .quiz-step legend { font-size: clamp(0.95rem, 4.4vw, 1.3rem); margin-bottom: 0.65rem; }
  .options { gap: 0.4rem; }
  .option { padding: 0.5rem 0.85rem; border-radius: 8px; }
  .option__t { font-size: 1rem; }
  .option__d { display: none; }               /* titles only on phones - keeps steps short */
  .quiz-step .field { margin-bottom: 0; }
  .quiz__nav { margin-top: clamp(0.75rem, 2.5vh, 1.4rem); }

  /* Work carousel becomes an ordinary horizontal swipe strip on mobile - the
     desktop pinned scroll-jack misbehaves on touch. Only the row scrolls. */
  .work__track { height: auto; }
  .work__pin { position: static; height: auto; display: block; overflow: visible; }
  .work-grid {
    transform: none !important;
    width: auto; max-width: 100%;
    overflow-x: auto; overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
    scroll-snap-type: x proximity;
    scroll-padding-left: var(--pad-x);   /* so snapping keeps the first card in line
                                            with the heading instead of eating the gutter */
    scrollbar-width: none;
    padding-right: var(--frame-pad);
  }
  .work-grid::-webkit-scrollbar { display: none; }
  .work-item { scroll-snap-align: start; }
}

/* Short phones (e.g. iPhone SE): compact the quiz harder so a 6-option step
   still fits the window without scrolling. */
@media (max-width: 640px) and (max-height: 720px) {
  #enquire { padding-block: 0.5rem; }
  #enquire h2 { font-size: 1.05rem; }
  #enquire .lede { display: none; }
  .quiz { margin-top: 0.7rem; }
  .quiz__progress { margin-bottom: 0.6rem; }
  .quiz-step legend { font-size: 0.95rem; margin-bottom: 0.5rem; }
  .options { gap: 0.3rem; }
  .option { padding: 0.4rem 0.8rem; }
  .option__t { font-size: 0.95rem; }
  .quiz__nav { margin-top: 0.7rem; }
  .btn-submit { padding: 0.6rem 1.4rem; min-height: 42px; }
}

/* =========================================================================
   HOME REDESIGN - fixed spinning ring; logo + copy scroll up through it
   ========================================================================= */

/* Header fixed to the top of the page */
.site-header { position: fixed; }

/* Instagram (left) / Enquire (right) */
.nav-ig {
  font-family: var(--font-body); font-weight: 700; font-size: var(--step-small);
  text-transform: uppercase; letter-spacing: 0.18em; color: var(--ink);
  padding: 0.5rem 0.2rem;
  transition: color 500ms cubic-bezier(0.4, 0, 0.2, 1);
}
.nav-ig:hover { color: var(--blue); }
.nav-enquire { color: var(--blue); transition: color 500ms cubic-bezier(0.4, 0, 0.2, 1); }  /* ENQUIRE in blue */
.nav-enquire:hover { color: var(--ink); }   /* hover simply turns charcoal */
.nav-enquire::after { content: none; }       /* drop the animated underline - hover is colour-only */

/* All TEXT gets a 0.5px stroke of its own colour (logos are images, unaffected) */
body { -webkit-text-stroke: 0.5px currentColor; text-stroke: 0.5px currentColor; }

/* ----- The fixed, always-spinning ring ----- */
/* .ring itself must NOT create a stacking context (no position/z-index/transform)
   so each fixed item's z-index compares with .content at the root - that's how
   near items paint in front of the content and far items behind it. */
.ring { pointer-events: none; }
.ring-item {
  position: fixed; top: 0; left: 0; margin: 0;
  pointer-events: none;
  width: clamp(130px, 14vw, 205px);
  aspect-ratio: 3 / 4;
  transform: translate(-50%, -50%);           /* JS overwrites with the projected position/scale */
  transform-origin: 50% 50%;
  overflow: hidden; border-radius: 3px;
  background: #e9e9e9;
  box-shadow: 0 24px 60px rgba(30,30,32,0.30);
  will-change: transform;
  backface-visibility: hidden;
}
.ring-item img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* ----- Scrolling content sits between the ring's near and far items ----- */
.content { position: relative; z-index: 500; }
/* Height is set by script.js (--hero-spacer-h) so the logo lands in the centre of
   the ring's open middle; the calc() is just the pre-JS fallback. */
.hero-spacer { height: var(--hero-spacer-h, calc(50vh - 4.5rem)); }
.planet { display: grid; place-items: center; padding-inline: var(--pad-x); }
/* The logo is a wordmark image + the blue star overlaid at its exact position in
   the original artwork (bbox 458,7 86×98 in the 1000×480 box), so the star can
   spin as the loading animation and land back in its natural spot. */
.planet-logo { position: relative; width: min(46vw, 460px); }
.logo-wordmark { display: block; width: 100%; height: auto; }
.logo-star {
  position: absolute; left: 45.8%; top: 1.4583%; width: 8.6%; height: auto;
  transform-origin: 50% 50%;
}
@keyframes star-spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
/* Spin while html.is-spinning - only the original star (not loop clones), never
   for reduced-motion readers. Starts and ends at the star's natural angle.
   (is-spinning outlives is-loading so the spin isn't restarted at reveal.) */
@media (prefers-reduced-motion: no-preference) {
  html.is-spinning .content:not([data-loop-clone]) .logo-star { animation: star-spin 4s linear infinite; }
}

/* ----- Loading splash: for the first beat only the star is visible; the rest of
   the page waits (hidden, loading in the background) and then fades in. The
   .ring-item rule is !important because the mobile back-fade writes inline
   opacity on the items every frame. Hiding items (not .ring) avoids giving the
   ring wrapper a stacking context, which would break the near/far layering. */
.site-header, .logo-wordmark {
  transition: opacity 0.6s ease;
}
/* Ring items only transition during the splash reveal (html.is-revealing, ~0.8s
   around the moment the page appears). The rest of the time the depth-fade is
   written every rendered frame and must track the spin with zero lag - any
   standing transition made the top-line fade smear behind fast scrolls. */
@media (min-width: 641px) {
  html.is-revealing .ring-item { transition: opacity 0.6s ease; }
}
html.is-loading .site-header,
html.is-loading .logo-wordmark,
html.is-loading .home-copy,
html.is-loading .home-deliverables,
html.is-loading .site-footer-min { opacity: 0; }
html.is-loading .ring-item { opacity: 0 !important; }

/* ----- Centre reveal: every text block (and each loop copy's logo) is hidden
   while it sits below the bottom line of photos, and fades in (500ms) once it
   has scrolled up into the ring's open centre - script.js toggles .in-centre
   from the element's position every frame, so it holds for every loop. */
/* Hidden state carries a QUICK transition, so when a block drops back below the
   orbit line (scrolling up) it disappears at once instead of lingering. */
.planet, .home-lede, .home-prose p, .deliverables-list li, .footer-copy {
  opacity: 0; transition: opacity 140ms ease;
}
/* The revealed state carries the gentle 500ms fade — used only when a block
   rises into the centre. (CSS uses the transition of the state being entered.) */
.planet.in-centre, .home-lede.in-centre, .home-prose p.in-centre,
.deliverables-list li.in-centre, .footer-copy.in-centre {
  opacity: 1; transition: opacity 500ms ease;
}

/* ----- Centred home copy ----- */
/* padding-top = gap under the logo (+25%); padding-bottom trimmed 25% (half the
   gap above the deliverables). */
.home-copy { text-align: center; padding-top: clamp(7.5rem, 20vh, 15rem); padding-bottom: calc(var(--section-y) * 0.75); }
.home-lede {
  font-size: clamp(1.25rem, 1.9vw, 1.6rem); color: var(--ink);
  max-width: 34ch; margin-inline: auto; line-height: 1.4;
}
.home-prose {
  margin-top: clamp(2rem, 5vw, 3.5rem);
  max-width: 46ch; margin-inline: auto;
  font-size: var(--step-body); color: var(--ink);
}
.home-prose p + p { margin-top: 1.2rem; }

/* ----- Deliverables (centred, stacked) ----- */
/* padding-top = other half of the gap above LAUNCH FILM (−25%); padding-bottom =
   part of the gap above the © line (−25%). */
.home-deliverables { text-align: center; padding-block: calc(var(--section-y) * 0.75); }
.deliverables-list { list-style: none; padding: 0; margin: 0 auto; max-width: 44ch; }
.deliverables-list li { margin-bottom: clamp(2.25rem, 5vw, 3.5rem); }
.deliverables-list li:last-child { margin-bottom: 0; }
.deliverables-list h3 {
  font-family: var(--font-display); font-weight: 400;
  text-transform: uppercase; letter-spacing: 0.18em;
  font-size: clamp(1.05rem, 1.5vw, 1.3rem); color: var(--ink);
  margin-bottom: 0.65rem;
}
.deliverables-list p { font-size: var(--step-body); color: var(--ink); max-width: 34ch; margin-inline: auto; }

/* ----- Minimal footer (just the copyright, per the mockup) ----- */
/* Top pad = gap above © (−25%), bottom pad = gap below © (−25%). */
.site-footer-min { text-align: center; padding: clamp(3rem, 9vh, 6rem) var(--pad-x) clamp(2.25rem, 6vh, 3.75rem); }
.footer-copy { font-size: var(--step-small); letter-spacing: 0.1em; color: var(--ink); }

/* The enquiry overlay must sit above the fixed ring and header */
.enquire-overlay { z-index: 2000; }
.enquire-close { z-index: 2010; }
.site-header { z-index: 1500; }
