/* ==========================================================================
   TAN STUDIOS CREATIVE LTD — tanstudios.co.uk
   Plain CSS, no build step. Design reference: Figma frame 1512 × 982.

   Every design value below is taken from that frame. Anything that must hold
   its proportion as the window changes is written as a clamp() whose middle
   term lands exactly on the design value at 1512 × 982.
   ========================================================================== */

/* --- Fonts (self-hosted; no third-party requests, so no consent banner) --- */

@font-face {
  font-family: 'Jost';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('../fonts/jost-latin-wght-normal.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Jost';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('../fonts/jost-latin-ext-wght-normal.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Marcellus';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/marcellus-latin-400-normal.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Marcellus';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/marcellus-latin-ext-400-normal.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* --- Tokens --------------------------------------------------------------- */

:root {
  /* Colour */
  --ink: #000;
  --ink-muted: rgb(0 0 0 / 0.4);   /* nav (inactive) + footer detail, per design */
  --ink-form: rgb(0 0 0 / 0.6);    /* form labels + consent — 5.7:1, passes AA   */
  --error: #a4231b;                /* 7.4:1 on white                             */
  --success: #166534;              /* 7.1:1 — deliberately the same weight as    */
                                   /* the error red, so neither shouts louder    */
  --paper: #fff;

  /* Type */
  --font-serif: 'Marcellus', 'Times New Roman', serif;
  --font-sans: 'Jost', -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
  --lh-serif: 1.2539;   /* Marcellus' own metrics — identical to Figma "auto" */
  --lh-sans: 1.445;     /* Jost's own metrics                                 */

  /* Type scales on the SMALLER of width and height. A section has to fit one
     screen, so on a short wide window (1440 × 900, 1280 × 800 — very common
     laptops) height is the binding constraint. Sizing on vw alone overflows
     those by a few pixels, which is enough to break the one-screen layout.
     Both terms land on the same number at the design size of 1512 × 982. */
  --fs-nav: clamp(14px, 1.058vw, 16px);                          /* 16px @1512 */
  --fs-hero: clamp(26px, min(3.2077vw, 4.9390svh), 48.501px);    /* 48.5 @1512 */
  --fs-title: clamp(26px, min(2.9762vw, 4.5825svh), 45px);       /* 45   @1512 */
  --fs-solution: clamp(21px, min(2.3148vw, 3.5642svh), 35px);    /* 35   @1512 */
  --fs-body: clamp(16px, min(1.6534vw, 2.5458svh), 25px);        /* 25   @1512 */
  --fs-consent: clamp(13px, min(1.1905vw, 1.8330svh), 18px);     /* 18   @1512 */
  --fs-footer: clamp(13px, min(1.058vw, 1.6293svh), 16px);       /* 16   @1512 */
  --fs-privacy: clamp(15px, 1.058vw, 16px);                      /* 16   @1512 */

  /* Horizontal rhythm */
  --page-pad: clamp(20px, min(2.315vw, 3.5642svh), 35px);        /* 35 @1512 */
  --container: 1099px;
  --col-gap: clamp(16px, 1.3228vw, 20px);        /* 20   @1512 */

  /* Vertical rhythm — svh, so tall content compresses instead of overflowing */
  --pad-top: clamp(72px, 15.988svh, 157px);      /* 157  @982 */
  --gap-title: clamp(34px, 8.005svh, 78.6px);    /* 78.6 @982 */
  --gap-rows: clamp(14px, 2.342svh, 23px);       /* 23   @982 */
  --gap-consent: clamp(9px, 1.426svh, 14px);     /* 14   @982 */
  --gap-columns: clamp(52px, 16.517svh, 162.2px);/* 162  @982 */
  --gap-solution: clamp(14px, 3.075svh, 30.2px); /* 30.2 @982 */
  --h-textarea: clamp(104px, 20.265svh, 199px);  /* 199  @982 */
  --gap-button: clamp(20px, 4.481svh, 44px);     /* 44   @982 */
  --h-footer: calc(4 * var(--fs-footer) * var(--lh-sans) + var(--page-pad));

  /* Hero — 728 × 622 at 1512 × 982, capped so it never outgrows the viewport */
  --hero-w: min(728px, 48.148vw, 74.1svh);
  --hero-fade: 900ms;

  --focus: 2px solid var(--ink);
}

/* --- Reset ---------------------------------------------------------------- */

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

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

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: var(--fs-body);
  line-height: var(--lh-sans);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, p, ul, figure { margin: 0; }
ul { padding: 0; list-style: none; }
img, svg { display: block; max-width: 100%; }
a { color: inherit; }

:focus-visible {
  outline: var(--focus);
  outline-offset: 3px;
}

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

.skip-link {
  position: fixed;
  top: 8px; left: 8px;
  z-index: 100;
  padding: 10px 16px;
  background: var(--paper);
  color: var(--ink);
  font-size: 16px;
  text-decoration: none;
  box-shadow: 0 0 0 2px var(--ink);
  transform: translateY(-250%);
}
.skip-link:focus { transform: none; }

.container {
  width: min(var(--container), 100% - 2 * var(--page-pad));
  margin-inline: auto;
}

/* --- Fixed chrome: logo + nav --------------------------------------------- */

.logo {
  position: fixed;
  top: 20px;
  left: 20px;
  z-index: 20;
  display: block;
  width: clamp(120px, 11.045vw, 167px);   /* 167 @1512 */
  color: var(--ink);
}
.logo img { width: 100%; height: auto; }

.nav {
  position: fixed;
  top: 35px;
  right: var(--page-pad);
  z-index: 20;
}
.nav__list {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  font-size: var(--fs-nav);
  line-height: var(--lh-sans);
  /* 33px between line tops in the design; the line box is already 1.445em */
  gap: calc(33px - var(--fs-nav) * var(--lh-sans));
}
.nav__link {
  display: block;
  font-size: var(--fs-nav);
  font-weight: 400;
  color: var(--ink-muted);
  text-decoration: none;
  transition: color 200ms ease;
}
.nav__link:hover { color: var(--ink); }
.nav__link[aria-current='true'] {
  font-weight: 500;
  color: var(--ink);
}

/* --- Sections ------------------------------------------------------------- */

.section { position: relative; min-height: 100svh; }
.section:focus { outline: none; }

/* Section 1 — About us ------------------------------------------------------ */

.section--about { display: grid; place-items: center; }

.hero {
  display: grid;
  place-items: center;
  width: 100%;
}
.hero > * { grid-area: 1 / 1; }

/* Two copies of the headline. The black one sits under the photograph; the
   white one sits on top of it, clipped to the photograph's box. So the words
   read black on paper and white across the image — exactly as designed. Both
   copies share font, size and centre point, so they can never drift apart. */
.hero__title {
  font-family: var(--font-serif);
  font-weight: 400;
  font-size: var(--fs-hero);
  line-height: var(--lh-serif);
  text-align: center;
  white-space: nowrap;
  width: max-content;
  margin: 0;
}

.hero__media {
  position: relative;
  width: var(--hero-w);
  aspect-ratio: 728 / 622;
  overflow: hidden;
  background: #efece7;
}

.hero__frames { position: absolute; inset: 0; }

.hero__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 45%;   /* matches the crop in the Figma frame */
  opacity: 0;
  transition: opacity var(--hero-fade) ease-in-out;
}
.hero__img.is-active { opacity: 1; }

.hero__title--knockout {
  position: absolute;
  z-index: 3;                    /* above every rotating frame */
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  display: block;
  color: var(--paper);
  pointer-events: none;
}

/* Section 2 — Solutions ----------------------------------------------------- */

.section--solutions,
.section--contact { padding-top: var(--pad-top); }

.section__title {
  font-family: var(--font-serif);
  font-weight: 400;
  font-size: var(--fs-title);
  line-height: var(--lh-serif);
}

.solutions {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--col-gap);
  margin-top: var(--gap-columns);
}
.solution__title {
  font-family: var(--font-serif);
  font-weight: 400;
  font-size: var(--fs-solution);
  line-height: var(--lh-serif);
  /* Reserve two lines so all three bodies begin on the same line, as designed */
  min-height: calc(2em * var(--lh-serif));
  margin-bottom: var(--gap-solution);
}
.solution__body { font-size: var(--fs-body); line-height: var(--lh-sans); }

/* Section 3 — Contact us ---------------------------------------------------- */

.section--contact { padding-bottom: calc(var(--h-footer) + var(--gap-rows)); }

.form { margin-top: var(--gap-title); }

.form__rows {
  display: flex;
  flex-direction: column;
  gap: var(--gap-rows);
}
.form__row {
  display: grid;
  gap: var(--col-gap);
}
.form__row--halves { grid-template-columns: 1fr 1fr; }   /* 539 : 540 @1512 */
.form__row--split  { grid-template-columns: 726fr 353fr; }
.form__row--full   { grid-template-columns: 1fr; }

.field { position: relative; min-width: 0; }

.field__input {
  width: 100%;
  font-family: var(--font-sans);
  font-size: var(--fs-body);
  line-height: var(--lh-sans);
  color: var(--ink);
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--ink);
  border-radius: 0;
  padding: 0 0 4px;
  appearance: none;
}
.field__input::placeholder { color: var(--ink-form); opacity: 1; }

/* Focus lives in the underline, not a box: the 1px rule thickens to 3px.
   box-shadow rather than border-width, so nothing shifts. Plain :focus, not
   :focus-visible — text fields match :focus-visible on mouse clicks anyway,
   so the distinction buys nothing here. */
.field__input { caret-color: var(--ink); }
.field__input:focus {
  outline: none;
  box-shadow: 0 2px 0 0 var(--ink);
}
.field__input:focus::placeholder { color: var(--ink); }
.field__input[aria-invalid='true']:focus {
  box-shadow: 0 2px 0 0 var(--error);
}

.field__input--select {
  color: var(--ink-form);
  cursor: pointer;
  padding-right: 30px;
  /* lsicon:down-filled from the design, redrawn: 9.64 × 5.7 in a 20 × 20 box */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M5.18 7.06 10 12.76l4.82-5.7' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0 center;
  background-size: 20px 20px;
}
.field__input--select:valid { color: var(--ink); }
.field__input--select option { color: var(--ink); }

.field__input--textarea {
  height: var(--h-textarea);
  resize: vertical;
  padding-bottom: 8px;
}

.field__error {
  margin-top: 6px;
  font-size: var(--fs-consent);
  line-height: 1.35;
  color: var(--error);
}
.field__input[aria-invalid='true'] {
  border-bottom-width: 2px;
  border-bottom-color: var(--error);
}

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

.form__consent {
  margin-top: var(--gap-consent);
  font-size: var(--fs-consent);
  line-height: var(--lh-sans);
  color: var(--ink-form);
}
.form__consent a { color: inherit; text-underline-offset: 2px; }

.form__actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  margin-top: var(--gap-button);
}
.form__status {
  margin: 0;
  font-size: var(--fs-consent);
  line-height: 1.4;
}
.form__status.is-error { color: var(--error); }
.form__status.is-success { color: var(--success); }

.button {
  flex: none;
  width: clamp(122px, 10.979vw, 166px);   /* 166 @1512 */
  height: clamp(38px, 4.888svh, 48px);    /*  48 @982  */
  display: grid;
  place-items: center;
  font-family: var(--font-sans);
  font-size: var(--fs-body);
  line-height: 1;
  color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--ink);
  border-radius: 0;
  cursor: pointer;
  transition: background-color 180ms ease, color 180ms ease;
}
.button:hover:not(:disabled) { background: var(--ink); color: var(--paper); }
.button:disabled { cursor: progress; opacity: 0.55; }

/* --- Footer --------------------------------------------------------------- */

.site-footer {
  position: fixed;
  left: var(--page-pad);
  right: var(--page-pad);
  bottom: var(--page-pad);
  z-index: 15;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 24px;
  font-size: var(--fs-footer);
  line-height: var(--lh-sans);
  color: var(--ink-muted);
  pointer-events: none;
}
.site-footer a, .site-footer span { pointer-events: auto; }
.site-footer__name { color: var(--ink); }
.site-footer a { text-decoration: none; }
.site-footer a:hover { text-decoration: underline; }
.site-footer__meta {
  display: flex;
  gap: clamp(12px, 1.3228vw, 20px);
  white-space: nowrap;
}

/* In the Figma frames the footer belongs to Contact and Privacy only. With JS
   we reveal it when Contact comes into view; with JS off it simply stays put,
   so the statutory disclosure is never hidden from anyone. */
html.js .page--home .site-footer {
  opacity: 0;
  visibility: hidden;
  transition: opacity 320ms ease, visibility 0s linear 320ms;
}
html.js .page--home.footer-visible .site-footer {
  opacity: 1;
  visibility: visible;
  transition: opacity 320ms ease, visibility 0s;
}

/* --- Privacy page --------------------------------------------------------- */

.page--privacy {
  display: flex;
  flex-direction: column;
  min-height: 100svh;
}
.page--privacy main {
  flex: 1 0 auto;
  padding-top: var(--pad-top);
  padding-bottom: clamp(40px, 8svh, 72px);
}
.page--privacy .site-footer {
  position: static;
  left: auto; right: auto; bottom: auto;
  width: min(100% - 2 * var(--page-pad), 100%);
  margin: 0 var(--page-pad) var(--page-pad);
}

.prose {
  margin-top: clamp(28px, 5.906svh, 58px);   /* body starts at y 255 @982 */
  font-size: var(--fs-privacy);
  line-height: var(--lh-sans);
  /* The design sets the measure to the full 1099px container. If you ever want
     shorter, easier-to-read lines here, add: max-width: 80ch; */
}
.prose p + p { margin-top: 1.445em; }
.prose strong { font-weight: 600; }
.prose a { text-underline-offset: 2px; }

/* --- Scroll reveals -------------------------------------------------------- */

/* Scrolling is native — nothing intercepts it (see the r4 note in main.js).
   The section-arrival effect is content revealing into place: elements marked
   data-reveal start slightly low and transparent, and transition in when the
   observer marks them .is-visible. Scoped to html.js so that without
   JavaScript nothing is ever hidden. Children of a data-reveal-group are
   staggered via --reveal-delay, set by the script. */
html.js [data-reveal] {
  opacity: 0;
  transform: translateY(26px);
  transition:
    opacity 700ms cubic-bezier(0.22, 1, 0.36, 1),
    transform 700ms cubic-bezier(0.22, 1, 0.36, 1);
  transition-delay: var(--reveal-delay, 0ms);
}
html.js [data-reveal].is-visible {
  opacity: 1;
  transform: none;
}

/* --- Small screens -------------------------------------------------------- */

@media (max-width: 779px) {
  :root { --hero-w: min(84vw, 400px); }

  /* The headline stays wider than the photograph, so it still breaks past both
     edges the way it does on the desktop layout. */
  .hero__title {
    white-space: normal;
    width: min(94vw, 448px);
    font-size: clamp(26px, 7.2vw, 34px);
  }

  /* A fixed three-line nav would sit on top of the form as you scroll, so on
     small screens the chrome becomes a compact bar instead. */
  body::before {
    content: '';
    position: fixed;
    inset: 0 0 auto 0;
    height: 56px;
    z-index: 19;
    background: rgb(255 255 255 / 0.94);
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
  }
  .nav {
    top: 0;
    right: var(--page-pad);
    height: 56px;
    display: flex;
    align-items: center;
  }
  .nav__list {
    flex-direction: row;
    align-items: center;
    gap: clamp(10px, 3.6vw, 16px);
    font-size: clamp(12px, 3.4vw, 14px);
  }
  .nav__link { font-size: inherit; }

  .solutions {
    grid-template-columns: 1fr;
    gap: clamp(28px, 5vh, 44px);
  }
  .solution__title { min-height: 0; margin-bottom: 12px; }

  .form__row--halves,
  .form__row--split { grid-template-columns: 1fr; }
  .form__rows { gap: 22px; }

  .form__actions { flex-direction: column-reverse; align-items: stretch; }
  .button { width: 100%; height: 52px; }

  /* One section per screen on mobile too. Without the full height, Solutions
     ends early and the Contact heading creeps up underneath it. Sections that
     need more room than the screen (the form) still grow past it. */
  .section {
    min-height: 100svh;
    padding-top: clamp(92px, 15vh, 130px);
    padding-bottom: clamp(40px, 8vh, 72px);
  }
  .section--about { min-height: 100svh; padding: 0; }
  .section--contact { padding-bottom: 40px; }

  .site-footer {
    position: static;
    left: auto; right: auto; bottom: auto;
    flex-direction: column;
    align-items: flex-start;
    gap: 10px;
    margin: 0;
    padding: 40px var(--page-pad) 32px;
  }
  html.js .page--home .site-footer,
  html.js .page--home.footer-visible .site-footer {
    opacity: 1;
    visibility: visible;
  }
  .page--privacy .site-footer { margin: 0; }

  .logo {
    top: 10px;
    left: var(--page-pad);
    width: clamp(104px, 30vw, 132px);
  }
}

/* --- Reduced motion ------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  /* Nothing hides, nothing rises — the content is simply there. */
  html.js [data-reveal] {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* --- Print ---------------------------------------------------------------- */

@media print {
  .nav, .skip-link { display: none; }
  .section { min-height: 0; page-break-inside: avoid; }
  .site-footer { position: static; opacity: 1 !important; visibility: visible !important; }
}
