/* ==========================================================================
   Shirune Studio — one stylesheet, no build step, no framework.
   --------------------------------------------------------------------------
   Read it top to bottom:

     0. Tokens              every colour, size and spacing lives here
     1. Base                reset, typography, shared helpers
     2. Pieces              pill, button, project card — reused across sections
     3. Header              fixed bar, the veil that thickens on scroll, menu
     4. Hero                full-height photograph
     5. About               the lede that lights up word by word
     6. Services            three tabs driven by native radios
     7. Clients
     8. Projects            the rail that slides while the section is pinned
     9. Testimonials        scroll-snap carousel
    10. Journal
    11. FAQ                 native <details>
    12. Footer
    13. Motion              scroll reveals and reduced-motion

   Two rules worth knowing before you edit:

   — the type scale is declared once in part 0 and redeclared at each
     breakpoint. No heading has its own media query: change --h2 and every
     h2 on the page follows.
   — anything hidden before it animates is written under `html.js`. Without
     JavaScript nothing is hidden, so the page never ends up blank.
   ========================================================================== */


/* ==========================================================================
   0. Tokens
   ========================================================================== */

:root {
  /* --- Colours ---------------------------------------------------------- */
  --ink: #000;                  /* headings and body text on light */
  --ink-soft: #5b5b5b;          /* secondary paragraphs */
  /* The lede before a word lights up. The original uses a very pale grey that
     only reaches 2.6:1 against the section background — unreadable for anyone
     who does not scroll. This one is 4.6:1 and the effect still reads. */
  --ink-faint: #6f6f6f;
  --paper: #fff;
  --paper-grey: #f5f5f5;        /* the alternating section background */
  --bark: #2f2c25;              /* project card titles */
  --ghost: #dedede;             /* the giant word behind the rail */
  --chip: #e4e4e4;              /* the small icon squares in "About" */

  /* Three shades of the same green. The full one carries white text on a
     solid background, the dark one is its hover, the light one is the only
     shade legible on a photograph. Changing one means changing all three —
     contrast ratios are listed in the README. */
  --green: #506e61;
  --green-dark: #3f574d;
  --green-light: #8fb0a1;

  /* --- Type ------------------------------------------------------------- */
  --font-body: "Inter Tight", system-ui, sans-serif;
  --font-display: "Libre Caslon Condensed", Georgia, serif;
  --font-label: "Instrument Serif", Georgia, serif;

  --h1: 80px;
  --h2: 60px;
  --h3: 40px;
  --h4: 34px;
  --h5: 30px;
  --h6: 24px;
  --p-lg: 18px;
  --p: 16px;
  --p-sm: 14px;
  --p-xs: 12px;

  --lh-flat: 100%;
  --lh-tight: 120%;
  --lh-mid: 140%;
  --lh-loose: 160%;

  --track-xl: -2px;             /* letter-spacing of the biggest headings */
  --track-lg: -1px;
  --track-sm: -0.06px;

  /* --- Space and shape -------------------------------------------------- */
  --gutter: 40px;               /* left and right padding of every section */
  --band: 120px;                /* vertical padding of a standard section */
  --shell: 1440px;              /* the widest the content ever gets */

  --r-sm: 4px;
  --r: 6px;
  --r-md: 10px;
  --r-lg: 12px;
  --r-xl: 20px;

  /* --- Motion ----------------------------------------------------------- */
  --ease-out: cubic-bezier(0.165, 0.84, 0.44, 1);   /* Webflow's "outQuart" */
  --ease-both: cubic-bezier(0.455, 0.03, 0.515, 0.955); /* "inOutQuad" */
  --ease-swing: cubic-bezier(0.645, 0.045, 0.355, 1);   /* "inOutCubic" */
}

@media (max-width: 991px) {
  :root {
    --h1: 60px;
    --h2: 40px;
    --h3: 40px;
    --gutter: 30px;
  }
}

@media (max-width: 767px) {
  :root {
    --h1: 46px;
    --h2: 30px;
    --h3: 30px;
    --h4: 24px;
    --h5: 24px;
    --h6: 22px;
    --p-lg: 16px;
    --gutter: 20px;
    --band: 60px;
  }
}


/* ==========================================================================
   1. Base
   ========================================================================== */

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

html {
  /* `clip`, never `hidden`: `hidden` would turn the root into a scroll
     container and break every `position: sticky` further down the page. */
  overflow-x: clip;
  /* No `scroll-behavior: smooth` here on purpose. The page is 12,500px tall:
     a smooth "Back to top" would crawl through every section for several
     seconds. The testimonial carousel asks for smooth scrolling explicitly,
     where the distance is one card. */
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--p);
  line-height: var(--lh-mid);
  letter-spacing: var(--track-sm);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, p, figure, blockquote, ul { margin: 0; padding: 0; }
ul { list-style: none; }
img, svg { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }

/* One focus ring for the whole page. */
:focus-visible {
  outline: 2px solid var(--green-light);
  outline-offset: 3px;
  border-radius: 2px;
}

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

.skip-link {
  position: absolute;
  left: 16px; top: -100px;
  z-index: 300;
  padding: 12px 20px;
  background: var(--paper);
  color: var(--ink);
  border-radius: var(--r);
  transition: top 0.2s;
}
.skip-link:focus { top: 16px; }

/* The <symbol> library at the top of the document must not take up space. */
.sprite { position: absolute; width: 0; height: 0; }

/* --- Layout scaffolding --------------------------------------------------- */

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

.section {
  position: relative;
  padding-block: var(--band);
}
.section--grey { background: var(--paper-grey); }

/* --- Section headers ------------------------------------------------------ */

.head {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 20px;
  text-align: center;
}
.head--left { align-items: flex-start; text-align: left; }

.head--split {
  flex-direction: row;
  align-items: flex-end;
  justify-content: space-between;
  gap: 20px;
  text-align: left;
}
.head--bottom { align-items: flex-end; }

.head__side {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 20px;
  max-width: 500px;
}

.head__title {
  max-width: 600px;
  font-family: var(--font-body);
  font-size: var(--h2);
  font-weight: 400;
  line-height: var(--lh-tight);
  letter-spacing: var(--track-lg);
}
.head__title--left { text-align: left; }
.head--split .head__title { max-width: 500px; }

.head__desc {
  max-width: 400px;
  color: var(--ink-soft);
  line-height: var(--lh-loose);
}

/* The italic serif words inside a heading. */
em {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 400;
  /* Libre Caslon sits lower than Inter Tight; 130% keeps the two on the same
     baseline inside a mixed line. */
  line-height: 130%;
}

@media (max-width: 991px) {
  .head--split {
    flex-direction: column;
    align-items: flex-start;
  }
  .head--bottom { align-items: flex-start; }
}


/* ==========================================================================
   2. Pieces reused across sections
   ========================================================================== */

/* --- The small serif pill above a heading --------------------------------- */

.pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 16px;
  background: var(--paper);
  border-radius: var(--r);
  font-family: var(--font-label);
  font-size: var(--p-sm);
  line-height: var(--lh-tight);
  letter-spacing: normal;
  color: var(--green);
  text-transform: uppercase;
}
.pill img { width: 14px; height: 14px; }

/* --- Button ---------------------------------------------------------------
   The label is printed twice, one copy above the other inside a box with
   `overflow: hidden`. On hover both slide up by exactly their own height, so
   the first leaves through the top while the second arrives from below. */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  flex: 0 0 auto;
  height: 48px;
  padding: 0 30px;
  background: var(--green);
  color: var(--paper);
  border-radius: var(--r-md);
  font-size: var(--p);
  letter-spacing: var(--track-sm);
  transition: background-color 0.3s var(--ease-both);
}
.btn:hover { background: var(--green-dark); }

.btn--light { background: var(--paper); color: var(--ink); }
.btn--light:hover { background: #ededed; }

.btn__text {
  display: grid;
  height: 1.25em;
  line-height: 1.25;
  overflow: hidden;
}
.btn__text > span {
  grid-area: 1 / 1;
  transition: transform 0.4s var(--ease-both);
}
.btn__text > span:last-child { transform: translateY(100%); }
.btn:hover .btn__text > span:first-child { transform: translateY(-100%); }
.btn:hover .btn__text > span:last-child { transform: translateY(0); }

.btn__arrow {
  width: 16px;
  height: 12px;
  fill: currentColor;
  transition: transform 0.4s var(--ease-both);
}
.btn:hover .btn__arrow { transform: translateX(10px); }

/* --- Project card ---------------------------------------------------------
   Same card in the hero and in the rail; only the frame ratio and the width
   change between the two. */

.card {
  display: flex;
  flex-direction: column;
  gap: 20px;
  width: 100%;
  padding: 12px 12px 18px;
  background: var(--paper);
  border-radius: var(--r);
}

/* The frame has a fixed height, not a ratio: that is what keeps the six cards
   of the rail the same height once they stack on a phone. */
.card__frame {
  display: block;
  width: 100%;
  height: 318px;
  border-radius: var(--r);
  overflow: hidden;
}
.card__frame img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.5s var(--ease-swing);
}
.card:hover .card__frame img,
.card:focus-visible .card__frame img { transform: scale(1.2); }

.card__body {
  display: flex;
  flex-direction: column;
  gap: 20px;
  width: 100%;
}
.card__title {
  font-family: var(--font-display);
  font-size: var(--h5);
  line-height: 100%;
  letter-spacing: var(--track-lg);
  color: var(--bark);
}

.card__tags {
  display: flex;
  gap: 20px;
}
.card__tags > span {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 120px;
  height: 26px;
  background: rgb(153 153 153 / 0.17);
  font-size: var(--p-sm);
  line-height: 1;
}

.card__more {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: var(--p-sm);
  line-height: var(--lh-loose);
}
/* The arrow leaves through the right while its twin arrives from the left. */
.card__arrow {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 25px;
  padding-inline: 10px;
  border: 1px solid var(--ink);
  border-radius: var(--r);
  overflow: hidden;
}
.card__arrow svg {
  width: 10px;
  height: 8px;
  fill: currentColor;
  transition: transform 0.3s var(--ease-both);
}
.card__arrow svg:first-child { position: absolute; transform: translateX(-22px); }
.card:hover .card__arrow svg { transform: translateX(22px); }
.card:hover .card__arrow svg:first-child { transform: translateX(0); }


/* ==========================================================================
   3. Header
   --------------------------------------------------------------------------
   Two things move here, both written by main.js:

     --veil     0 → 1 over the first 9% of the page, exactly like the original.
                It thickens the bar's background and turns the pill behind the
                links from dark to light.
     .is-hidden the bar slides out of the way while you scroll down and comes
                back the moment you scroll up.
   ========================================================================== */

.site-header {
  position: fixed;
  inset: 0 0 auto;
  z-index: 200;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 20px var(--gutter);
  background: rgb(0 0 0 / calc(0.6 * var(--veil, 0)));
  backdrop-filter: blur(5px);
  -webkit-backdrop-filter: blur(5px);
  transition: transform 0.5s var(--ease-both), background-color 0.5s linear;
}
.site-header.is-hidden { transform: translateY(-100%); }

.site-header__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  max-width: var(--shell);
}

.brand img { width: 152px; height: 28px; }

.nav {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 10px;
  border-radius: 8px;
  /* From rgb(0 0 0 / .2) at the top of the page to rgb(255 255 255 / .34)
     once the bar is veiled — the same two values the original interpolates. */
  background: color-mix(in srgb,
    rgb(255 255 255 / 0.34) calc(var(--veil, 0) * 100%),
    rgb(0 0 0 / 0.2));
  backdrop-filter: blur(40px);
  -webkit-backdrop-filter: blur(40px);
}

.nav__link {
  padding: 6px 16px;
  border-radius: var(--r-sm);
  color: var(--paper);
  line-height: 1;
  transition: background-color 0.3s var(--ease-both);
}
.nav__link:hover { background: rgb(0 0 0 / 0.16); }
.nav__link.is-current { background: rgb(0 0 0 / 0.16); font-weight: 500; }

.site-header__cta { height: 48px; }

/* --- Burger and mobile panel ---------------------------------------------- */

.burger {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 6px;
  width: 42px;
  height: 40px;
}
.burger__bar {
  display: block;
  width: 42px;
  height: 2px;
  border-radius: 1px;
  background: var(--paper);
  transition: transform 0.3s var(--ease-both);
}

.menu {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: center;
  gap: 40px;
  padding: 16px 16px 40px;
  background: var(--paper);
  /* Off-screen by default, brought back by the script. Sitting at 120% rather
     than 100% keeps its shadow out of sight too. */
  transform: translateX(120%);
  transition: transform 0.8s var(--ease-swing);
  visibility: hidden;
}
.menu.is-open { transform: translateX(0); visibility: visible; }

.menu__top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
}
.menu__close {
  position: relative;
  width: 30px;
  height: 30px;
}
.menu__close span {
  position: absolute;
  left: 0; top: 14px;
  width: 30px; height: 2px;
  border-radius: 1px;
  background: var(--ink);
}
.menu__close span:first-child { transform: rotate(45deg); }
.menu__close span:last-child { transform: rotate(-45deg); }

.menu__links {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 40px;
}
.menu__link {
  color: var(--ink);
  font-size: var(--h1);
  line-height: var(--lh-flat);
  text-transform: capitalize;
}
.menu__legal {
  font-size: var(--p-sm);
  color: var(--ink-soft);
}

@media (max-width: 991px) {
  .site-header { padding: 10px var(--gutter); }
  .site-header__cta, .nav { display: none; }
  .burger { display: flex; }
  :root { --menu-gap: 30px; }
}
@media (max-width: 767px) {
  .burger { width: 24px; height: 40px; gap: 5px; }
  .burger__bar { width: 24px; }
  .menu { gap: 30px; padding: 16px; }
}
@media (max-width: 479px) {
  .site-header { padding-inline: 16px; }
  .menu { gap: 20px; padding: 24px 20px; }
  .menu__links { gap: 20px; }
}


/* ==========================================================================
   4. Hero
   ========================================================================== */

.hero {
  position: relative;
  z-index: 2;
}

.hero__photo {
  position: absolute;
  inset: 0;
  z-index: 1;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* Two veils, and they do different jobs.

   The one running downwards is the original's: it seats the bottom of the
   photo. The one running sideways is ours. White type over the pale left half
   of this photograph measured 1.08:1 — the headline was there, but you had to
   look for it. A gradient across the column the text occupies takes it to
   4.5:1 and leaves the glass roof on the right untouched, where the photograph
   is actually worth seeing. Darkening the whole image to reach the same figure
   would have taken 39% black over all of it. */
.hero__veil {
  position: absolute;
  inset: 0;
  z-index: 2;
  background:
    linear-gradient(to right, rgb(0 0 0 / 0.66), rgb(0 0 0 / 0.52) 48%, rgb(0 0 0 / 0) 78%),
    linear-gradient(rgb(0 0 0 / 0) 43%, rgb(0 0 0 / 0.6) 90%);
}

/* On a narrow screen the headline runs the full width, so a gradient across
   the page passes under it without ever covering its right-hand side — 1.10:1
   again on the last word. Below the template's own breakpoint the veil turns
   downwards instead, over the band the logo and the headline occupy. */
@media (max-width: 991px) {
  .hero__veil {
    background:
      linear-gradient(rgb(0 0 0 / 0.6), rgb(0 0 0 / 0.55) 42%, rgb(0 0 0 / 0) 62%),
      linear-gradient(rgb(0 0 0 / 0) 43%, rgb(0 0 0 / 0.6) 90%);
  }
}

.hero__shell {
  position: relative;
  z-index: 3;
}

.hero__inner {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 40px;
  padding: 150px 0 40px;
}
@media (min-width: 992px) {
  .hero__inner {
    min-height: 100vh;
    gap: 0;
  }
}

.hero__head {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 40px;
}

.hero__title {
  max-width: 650px;
  color: var(--paper);
  font-size: var(--h1);
  font-weight: 400;
  line-height: var(--lh-tight);
  letter-spacing: var(--track-lg);
}

.hero__foot {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 40px;
}
.hero__scroll {
  color: var(--paper);
  font-size: var(--p-lg);
  line-height: var(--lh-tight);
}

.card--hero {
  flex: 0 0 250px;
  width: 250px;
  padding: 6px;
}
.card--hero .card__frame { height: 114px; }
/* Fixed, not taken from the scale: the hero card keeps its 24px title at
   every width, exactly like the original. */
.card--hero .card__title { font-size: 24px; }

@media (max-width: 767px) {
  /* The original stops pushing the two halves apart and pins a 200px gap
     between the headline and the card instead. */
  .hero__inner { gap: 200px; }
  .hero__scroll { display: none; }
}


/* ==========================================================================
   5. About
   ========================================================================== */

.about__inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 60px;
}

.about__head {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 20px;
  max-width: 950px;
}

.about__lede {
  font-family: var(--font-display);
  font-size: var(--h4);
  line-height: var(--lh-mid);
  letter-spacing: normal;
  text-align: center;
}

/* Each word is wrapped by the script, then lit one after the other as the
   paragraph crosses the middle of the screen. Without JavaScript the text is
   simply black — nothing is hidden, nothing waits. */
.js .word {
  color: var(--ink-faint);
  transition: color 0.4s linear;
}
.js .word.is-lit { color: var(--ink); }

.about__figure {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  width: 100%;
  max-width: 648px;
  height: 376px;
  padding: 20px;
  border-radius: var(--r-lg);
  overflow: hidden;
}
.about__photo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.about__seal {
  position: relative;
  z-index: 2;
  width: 54px;
  height: 54px;
}
.about__caption {
  position: relative;
  z-index: 2;
  max-width: 300px;
  color: var(--paper);
  line-height: var(--lh-mid);
}

.about__points {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 40px;
}
.about__point {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: var(--p-lg);
  line-height: var(--lh-tight);
}
.about__icon {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 46px;
  width: 46px;
  height: 46px;
  padding: 6px;
  background: var(--chip);
  border-radius: 5px;
}
.about__icon img { width: 20px; height: 34px; object-fit: contain; }

@media (max-width: 767px) {
  .about__points {
    flex-direction: column;
    align-items: flex-start;
    gap: 20px;
  }
}


/* ==========================================================================
   6. Services
   --------------------------------------------------------------------------
   Three radio buttons, three labels, three panels — and `:has()` to connect
   them. No script is involved: the tabs work with JavaScript disabled, and
   the arrow keys move between them because they are a real radio group.
   ========================================================================== */

.services__inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 80px;
}

.tabs {
  position: relative;
  width: 100%;
}

.tabs__bar {
  position: absolute;
  inset: 0 0 auto;
  z-index: 3;
  display: flex;
  justify-content: center;
  gap: 20px;
  padding-top: 40px;
}

.tabs__tab {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 9px 10px;
  background: rgb(0 0 0 / 0.77);
  border-radius: var(--r);
  color: var(--paper);
  font-size: var(--p-sm);
  line-height: 1;
  cursor: pointer;
}
.tabs__dot {
  width: 6px;
  height: 6px;
  border-radius: 1000px;
  background: var(--paper);
  display: none;
}

.tabs__panels {
  position: relative;
  height: 600px;
  border-radius: 16px;
  overflow: hidden;
}

/* The three panels are stacked in the same box — the container carries the
   height, so switching tabs never moves the rest of the page. */
.panel {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: center;
  padding: 40px 0;
  opacity: 0;
  visibility: hidden;
  overflow: hidden;
}

/* Only the widest layout gives the block its full height. */
@media (min-width: 1440px) {
  .tabs__panels { height: 762px; }
}

.panel__photo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.panel__veil {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: rgb(0 0 0 / 0.28);
}
.panel__text {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 20px;
  max-width: 450px;
  padding-inline: 20px;
  text-align: center;
}
.panel__title {
  font-family: var(--font-display);
  font-size: var(--h3);
  font-weight: 500;
  line-height: 100%;
  letter-spacing: var(--track-lg);
  color: var(--paper);
}
.panel__desc {
  color: var(--paper);
  font-size: var(--p-sm);
  line-height: var(--lh-mid);
}

/* The three connections. Reading them out loud: "when the tabs block has the
   second radio checked, show the second panel and mark the second label". */
.tabs:has(#service-interior:checked) [data-panel="interior"],
.tabs:has(#service-architecture:checked) [data-panel="architecture"],
.tabs:has(#service-planning:checked) [data-panel="planning"] {
  opacity: 1;
  visibility: visible;
}
.tabs:has(#service-interior:checked) .tabs__tab:nth-child(1) .tabs__dot,
.tabs:has(#service-architecture:checked) .tabs__tab:nth-child(2) .tabs__dot,
.tabs:has(#service-planning:checked) .tabs__tab:nth-child(3) .tabs__dot {
  display: block;
}

/* The radios are off-screen, so the focus ring has to be drawn on the label. */
.tabs__radio:focus-visible + .tabs__radio + .tabs__radio + .tabs__bar .tabs__tab:nth-child(1),
.tabs__radio:focus-visible + .tabs__radio + .tabs__bar .tabs__tab:nth-child(2),
.tabs__radio:focus-visible + .tabs__bar .tabs__tab:nth-child(3) {
  outline: 2px solid var(--green-light);
  outline-offset: 3px;
}

@media (max-width: 767px) {
  .services__inner { gap: 60px; }
}
@media (max-width: 479px) {
  .tabs__bar { flex-direction: column; align-items: center; }
  .panel { padding-inline: 16px; }
}


/* ==========================================================================
   7. Clients
   ========================================================================== */

.clients { padding-block: 0; }

.clients__inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 40px;
  padding-block: 50px;
}
.clients__line {
  color: var(--ink-soft);
  font-size: var(--p-lg);
  line-height: var(--lh-mid);
  text-align: center;
}
.clients__list {
  display: flex;
  align-items: center;
  gap: 63px;
}
.clients__list img { height: auto; }

@media (max-width: 767px) {
  .clients__list {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 16px 63px;
    justify-items: center;
  }
}
@media (max-width: 479px) {
  .clients__inner { padding-block: 40px; }
  .clients__list { column-gap: 20px; }
}


/* ==========================================================================
   8. Projects
   --------------------------------------------------------------------------
   `.projects__track` is five screens tall and does nothing but provide the
   scroll distance. `.projects__stage` sticks to the top of the window for the
   whole of it, and the script turns the vertical progress into the rail's
   `scrollLeft`.

   The rail is a genuine scroll container: swipe it, or tab into a card, and
   it moves on its own — script or no script.
   ========================================================================== */

.projects { padding-bottom: 0; }

.projects__track {
  position: relative;
  height: 500vh;
}
.projects__stage {
  position: sticky;
  top: 10px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  height: 830px;
}
.projects__mask {
  position: relative;
  height: 100%;
  padding: 0 0 120px 32px;
  overflow: hidden;
}

.projects__ghost {
  position: absolute;
  left: 0;
  bottom: 0;
  z-index: 1;
  margin: 0;
  font-family: var(--font-display);
  font-size: 300px;
  line-height: 100%;
  letter-spacing: -21.37px;
  color: var(--ghost);
  text-transform: uppercase;
  white-space: nowrap;
}

.rail {
  position: relative;
  z-index: 3;
  display: flex;
  align-items: flex-start;
  gap: 40px;
  height: 710px;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  /* The original has no visible scrollbar here; the rail can still be swiped,
     and the arrow keys reach it because it is focusable. */
  scrollbar-width: none;
}
.rail::-webkit-scrollbar { display: none; }

.rail__item {
  display: flex;
  align-items: flex-end;
  flex: 0 0 378px;
  max-width: 386px;
  height: 547px;
}
/* Every other card hangs 163px lower — the offset the original uses. */
.rail__item--low { height: 710px; }

@media (max-width: 991px) {
  /* No more pinning: the rail becomes a plain carousel, but it keeps its
     staggered heights — the original only flattens them below 768px. */
  .projects__track { height: auto; }
  .projects__stage { position: static; height: auto; }
  .projects__mask { padding-right: 32px; }
  .projects__ghost { display: none; }
}
@media (max-width: 767px) {
  .projects__track { margin-top: 60px; }
  .projects__mask { padding: 0 20px 60px; }
  .rail {
    flex-direction: column;
    align-items: flex-end;
    gap: 40px;
    height: auto;
    overflow: visible;
  }
  .rail__item, .rail__item--low {
    flex: 0 0 auto;
    width: 100%;
    max-width: none;
    height: auto;
  }
}


/* ==========================================================================
   9. Testimonials
   ========================================================================== */

.quotes__viewport {
  position: relative;
  margin-top: 60px;
  padding-bottom: 60px;
  overflow: hidden;
}

.quotes__rail {
  display: flex;
  gap: 10px;
  padding-inline: var(--gutter);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  /* Without this the snap would align the first card on the padding edge and
     eat the left margin the moment the page loads. */
  scroll-padding-inline: var(--gutter);
  overscroll-behavior-x: contain;
  scrollbar-width: none;
}
.quotes__rail::-webkit-scrollbar { display: none; }

.quote {
  flex: 0 0 min(680px, 100%);
  scroll-snap-align: start;
}
.quote__inner {
  display: flex;
  gap: 10px;
  height: 425px;
}

.quote__portrait {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: center;
  flex: 0 0 322px;
  padding-bottom: 20px;
  border-radius: var(--r-lg);
  overflow: hidden;
}
.quote__portrait > img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.quote__veil {
  position: absolute;
  inset: 0;
  z-index: 2;
  background: linear-gradient(0deg, rgb(0 0 0 / 1), rgb(0 0 0 / 0) 39%);
}
.quote__person {
  position: relative;
  z-index: 3;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  max-width: 289px;
  color: var(--paper);
  text-align: center;
}
.quote__name { font-size: var(--h6); line-height: 100%; }
.quote__role { font-size: var(--p-sm); line-height: 100%; }
.quote__stars { width: 107px; height: auto; }

.quote__text {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  flex: 1 1 auto;
  min-width: 0;
  padding: 24px;
  background: rgb(240 240 240 / 0.62);
  border-radius: var(--r-lg);
}
.quote__text img { width: 111px; height: 20px; object-fit: contain; }
.quote__text p {
  color: var(--ink-soft);
  font-size: var(--p-lg);
  line-height: var(--lh-mid);
}

/* Sits inside the 60px strip at the bottom of the viewport, exactly where the
   original puts its two arrows — so the block keeps its 485px height. */
.quotes__nav {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  justify-content: center;
  gap: 12px;
}
.quotes__button {
  display: block;
  width: 31px;
  height: 31px;
  border-radius: 50%;
  transition: transform 0.3s var(--ease-both);
}
.quotes__button svg { width: 31px; height: 31px; }
.quotes__button:hover { transform: translateX(3px); }
.quotes__button--prev svg { transform: rotate(180deg); }
.quotes__button--prev:hover { transform: translateX(-3px); }

@media (max-width: 479px) {
  .quote__inner { flex-direction: column; gap: 10px; height: auto; }
  .quote__portrait { flex: 0 0 300px; height: 300px; }
  .quote__text { gap: 20px; justify-content: flex-start; }
}


/* ==========================================================================
   10. Journal
   ========================================================================== */

.journal__inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 60px;
}

.journal__list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px 20px;
  width: 100%;
}

.post {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: center;
  gap: 20px;
  min-height: 600px;
  padding: 20px 20px 40px;
  border-radius: var(--r-lg);
  overflow: hidden;
}
.post__photo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.5s var(--ease-swing);
}
.post:hover .post__photo,
.post:focus-visible .post__photo { transform: scale(1.2); }

.post__veil {
  position: absolute;
  inset: 0;
  z-index: 2;
  background: linear-gradient(0deg, rgb(0 0 0 / 0.69), rgb(0 0 0 / 0) 39%);
}
.post__meta {
  position: relative;
  z-index: 3;
  display: flex;
  gap: 20px;
}
.post__type,
.post__date {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 28px;
  color: var(--paper);
  font-size: var(--p-sm);
  line-height: var(--lh-tight);
}
.post__type {
  padding-inline: 10px;
  background: rgb(255 255 255 / 0.17);
  border-radius: var(--r-sm);
}
.post__title {
  position: relative;
  z-index: 3;
  max-width: 301px;
  color: var(--paper);
  font-size: var(--h6);
  line-height: var(--lh-tight);
  text-align: center;
}

@media (max-width: 767px) {
  .journal__list { grid-template-columns: minmax(0, 1fr); }
  .post { min-height: 452px; }
}


/* ==========================================================================
   11. FAQ
   --------------------------------------------------------------------------
   Native <details>: it opens without a line of JavaScript, and the browser
   handles the keyboard and the screen reader announcement for us. The height
   transition is applied to ::details-content where the browser supports it;
   elsewhere the panel simply appears, which is the correct fallback.
   ========================================================================== */

.faq__inner {
  display: flex;
  justify-content: space-between;
  gap: 100px;
}

.faq__side {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: flex-start;
  gap: 40px;
  flex: 0 0 500px;
}

.faq__list {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 16px;
  flex: 1 1 auto;
  min-width: 0;
  max-width: 769px;
}

.faq__item {
  padding: 0 24px 24px;
  background: var(--paper-grey);
}

.faq__question {
  /* Chromium leaves <summary> in content-box whatever the universal rule
     says, which would add the padding on top of the width. */
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  padding-top: 24px;
  align-self: stretch;
  list-style: none;
  cursor: pointer;
  font-size: var(--p-lg);
  line-height: var(--lh-mid);
}
.faq__question::-webkit-details-marker { display: none; }

.faq__icon {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  border-radius: var(--r-lg);
  background: rgb(255 255 255 / 0.5);
  transition: transform 0.5s var(--ease-both);
}
/* The square around the plus only exists on the widest layout; elsewhere the
   icon sits at its own size, which is what keeps a closed row at 73px. */
@media (min-width: 1440px) {
  .faq__icon { flex-basis: 40px; width: 40px; height: 40px; }
}
.faq__icon svg { width: 24px; height: 25px; color: var(--ink); }
.faq__item[open] .faq__icon { transform: rotate(45deg); }

.faq__answer { padding-top: 10px; }
.faq__answer p {
  max-width: 612px;
  color: var(--ink-soft);
  line-height: var(--lh-mid);
}

/* Chrome 131+ / Firefox 139+: the closed panel keeps a box we can animate. */
@supports selector(::details-content) {
  .faq__item::details-content {
    block-size: 0;
    overflow: hidden;
    transition: block-size 0.5s var(--ease-both), content-visibility 0.5s allow-discrete;
  }
  .faq__item[open]::details-content { block-size: auto; }
}

@media (max-width: 991px) {
  .faq__inner { flex-direction: column; gap: 100px; }
  .faq__side { flex: 0 0 auto; }
  .faq__list { max-width: none; }
}
@media (max-width: 479px) {
  .faq__inner { gap: 60px; }
  /* 24px above the question as everywhere else, plus the 10px the original
     adds on both sides at this width. */
  .faq__question { padding: 34px 0 10px; }
  .faq__icon { min-width: 36px; min-height: 36px; }
  .faq__icon svg { width: 20px; height: 21px; }
  .faq__answer p { line-height: 24px; }
}


/* ==========================================================================
   12. Footer
   ========================================================================== */

.site-footer {
  position: relative;
  overflow: hidden;
}
.site-footer__photo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.site-footer__inner {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 150px;
  padding: 40px 20px;
}

.site-footer__call {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 40px;
  width: 100%;
  max-width: var(--shell);
  padding-inline: 20px;
}
.site-footer__title {
  max-width: 500px;
  color: var(--paper);
  font-family: var(--font-label);
  font-size: var(--h2);
  line-height: 100%;
  letter-spacing: normal;
}

.site-footer__card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 60px;
  width: 100%;
  max-width: var(--shell);
  padding: 60px 40px;
  background: var(--paper);
  border-radius: var(--r-xl);
  overflow: hidden;
}
/* Two fixed heights, then free below 480px — the three the original uses. */
.site-footer__card { min-height: 700px; }
@media (min-width: 1440px) {
  .site-footer__card { min-height: 800px; }
}
.site-footer__wordmark {
  position: absolute;
  left: 0;
  right: 0;
  bottom: -39px;
  width: 100%;
  height: auto;
}

.site-footer__top {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 40px;
}
.site-footer__identity {
  display: flex;
  flex-direction: column;
  gap: 20px;
  max-width: 500px;
}
.site-footer__identity img { width: 152px; height: 28px; }
.site-footer__claim {
  font-size: var(--h5);
  line-height: var(--lh-mid);
}

.site-footer__back {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 20px;
  font-weight: 500;
  line-height: 1;
}
.site-footer__back svg {
  width: 11px;
  height: 14px;
  fill: currentColor;
  transition: transform 0.4s var(--ease-both);
}
.site-footer__back:hover svg { transform: translateY(-6px); }

.site-footer__menus {
  display: flex;
  gap: 40px;
}
.site-footer__menus > div {
  display: flex;
  flex-direction: column;
  gap: 20px;
  flex: 0 0 132px;
}
.site-footer__menu-title {
  color: var(--ink-soft);
  font-size: var(--p);
  line-height: 1;
  letter-spacing: normal;
}
.site-footer__menu {
  display: flex;
  flex-direction: column;
  gap: 14px;
  /* The <li> would otherwise keep the body's 140% line-height and make each
     row 6px taller than the link inside it. */
  line-height: 1;
}
.site-footer__menu a { display: block; }
.site-footer__menu a:hover { color: var(--green); }

.site-footer__legal {
  position: relative;
  z-index: 2;
  font-size: var(--p-sm);
  line-height: 1;
}

@media (max-width: 767px) {
  .site-footer__card { padding-inline: 20px; }
  .site-footer__top { flex-direction: column; align-items: flex-start; gap: 40px; }
}
@media (max-width: 479px) {
  .site-footer__card { min-height: 0; padding-bottom: 100px; }
  .site-footer__menus > div { flex: 0 0 auto; }
  .site-footer__claim { font-size: var(--h6); }
  .site-footer__back { font-size: var(--p-lg); }
  .site-footer__menus {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 40px;
  }
  .site-footer__menus > div { flex-basis: auto; }
  .site-footer__wordmark { bottom: -8px; }
  .site-footer__menu-title, .site-footer__menu a { font-size: var(--p-sm); }
}


/* ==========================================================================
   13. Motion
   --------------------------------------------------------------------------
   The hidden state is written under `html.js` on purpose: enhance.js adds
   that class before the first paint, so a page whose scripts fail to load
   shows everything instead of a column of empty blocks.
   ========================================================================== */

.js [data-reveal] {
  opacity: 0;
  transform: translateY(100px);
}
.js [data-reveal].is-in {
  opacity: 1;
  transform: none;
  transition: opacity 1s var(--ease-out), transform 1s var(--ease-out);
}

/* The header arrives from above, 200ms after the page settles. */
.js .site-header {
  opacity: 0;
  transform: translateY(-100px);
}
.js .site-header.is-in {
  opacity: 1;
  transform: none;
  transition: opacity 1s var(--ease-out) 0.2s, transform 1s var(--ease-out) 0.2s,
    background-color 0.5s linear;
}
/* Once it has arrived, hiding it on scroll takes over the transform. */
.js .site-header.is-in.is-hidden {
  transform: translateY(-100%);
  transition: transform 0.5s var(--ease-both), background-color 0.5s linear;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  /* Final states, immediately — delays included: a delay is movement spread
     over time. */
  .js [data-reveal],
  .js .site-header {
    opacity: 1;
    transform: none;
    transition: none;
  }
  .js .word { color: var(--ink); transition: none; }

  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-delay: 0s !important;
    transition-duration: 0.01ms !important;
    transition-delay: 0s !important;
  }
}
