/* Storyline Group — base elements + brand primitives.
   Depends on tokens.css for colours and @font-face only.

   ALL SIZING IS LITERAL PIXELS. Three breakpoints, desktop-first:
     (base rules)            desktop — 901px and up
     @media (max-width:900px) tablet
     @media (max-width:600px) phone

   Type scale                desktop / tablet / phone
     display (h1)              110 /  84 /  48
     h2                         54 /  45 /  35
     h3, subhead                25 /  23 /  20
     body                       18 /  17 /  16
     meta, small                15 /  14 /  13
     service statement          36 /  31 /  20

   Spacing steps   4 · 8 · 12 · 20 · 32 · 52 · 80 · 128
   Radii           6 · 12 · 24 · 40 · 999 (pill)
   Page gutter     58 / 36 / 20      Container max 1312
   Vertical bar    3px, or 6px bold
*/

/* ================================ RESET ================================ */

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

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

body {
  margin: 0;
  background: var(--sl-cream);
  color: var(--sl-ink);
  font-family: "aileron", "Aileron Local", system-ui, -apple-system, sans-serif;
  font-size: 18px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;

  /* Footer tethered to the bottom of the viewport on short pages (404, thanks)
     without pulling it up the page on long ones — main grows to fill whatever
     is left over, and is simply ignored when the content already overflows.
     dvh so mobile browser chrome doesn't leave a gap; vh is the fallback. */
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
}

body > main { flex: 1 0 auto; }

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

/* Links inherit their colour — the palette has no link blue, and every link on
   the site sits inside copy that already sets the right colour for its ground.
   Underline treatment matches .contact__email. */
a {
  color: inherit;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

/* ============================= TYPOGRAPHY =============================
   H1 = Rift Bold. Reserved for the most important statements; the guide caps
        it at two lines — longer headlines drop to the serif.
   H2 = Instrument Serif — secondary headlines and editorial moments.
   H3 = Aileron Bold — sub-headlines and section intros. */

.display,
h1 {
  margin: 0;
  font-family: "rift", "Bebas Neue", sans-serif;
  font-weight: 700;
  font-size: 110px;
  line-height: 0.92;
  letter-spacing: 0;
  /* Rift has a full lowercase set, so this is a design choice, not a
     constraint. Kept because every application in the guide sets display type
     in caps. Remove this line for the mixed-case alternative. */
  text-transform: uppercase;
  text-wrap: balance;
}

.headline-2,
h2 {
  margin: 0;
  font-family: "instrument-serif", "Instrument Serif Local", Georgia, serif;
  font-weight: 400;
  font-size: 54px;
  line-height: 1.08;
}

.subhead,
h3 {
  margin: 0;
  font-family: "aileron", "Aileron Local", system-ui, sans-serif;
  font-weight: 700;
  font-size: 25px;
  line-height: 1.25;
}

p { margin: 0 0 20px; max-width: 66ch; }
p:last-child { margin-bottom: 0; }

.meta {
  font-family: "aileron", "Aileron Local", system-ui, sans-serif;
  font-weight: 700;
  font-size: 15px;
  letter-spacing: 0.01em;
}

@media (max-width: 900px) {
  body { font-size: 17px; }
  .display, h1 { font-size: 84px; }
  .headline-2, h2 { font-size: 45px; }
  .subhead, h3 { font-size: 23px; }
  .meta { font-size: 14px; }
}
@media (max-width: 600px) {
  body { font-size: 16px; }
  .display, h1 { font-size: 48px; }
  .headline-2, h2 { font-size: 35px; }
  .subhead, h3 { font-size: 20px; }
  .meta { font-size: 13px; }
}

/* =============================== LAYOUT =============================== */

.container {
  width: min(100% - 116px, 1312px);   /* 116 = 58px gutter × 2 */
  margin-inline: auto;
}

.section { padding-top: 128px; padding-bottom: 128px; }

@media (max-width: 900px) {
  .container { width: min(100% - 72px, 1312px); }   /* 36px gutter */
  .section { padding-top: 96px; padding-bottom: 96px; }
}
@media (max-width: 600px) {
  .container { width: min(100% - 40px, 1312px); }   /* 20px gutter */
  .section { padding-top: 64px; padding-bottom: 64px; }
}

/* Inverted / accent sections. Used selectively — cream stays dominant. */
.section--ink    { background: var(--sl-ink);    color: var(--sl-cream); }
.section--butter { background: var(--sl-butter); color: var(--sl-ink); }
.section--teal   { background: var(--sl-teal);   color: var(--sl-cream); }
/* Sky is a secondary colour, which the guide reserves for accents. Kept here
   as a section ground only for the contact block — see the wireframe notes. */
.section--sky    { background: var(--sl-sky);    color: var(--sl-ink); }
/* Orange, likewise a secondary. Ink text only: ink on orange is 7.51:1, cream
   on orange is 1.87:1 and fails outright. See the wireframe notes — this ground
   sits directly above the sky contact block, which needs a decision. */
.section--orange { background: var(--sl-orange); color: var(--sl-ink); }

/* ======================= VERTICAL LINE SYSTEM ========================= */

/* Paragraph anchor / highlight — a rule down the left edge of a lede or quote. */
.bar-anchor {
  border-left: 6px solid currentColor;
  padding-left: 20px;
}

/* Inline bar, as it sits beside the logotype. */
.bar::before {
  content: "";
  display: inline-block;
  width: 3px;
  height: 1em;
  margin-right: 8px;
  background: currentColor;
  vertical-align: -0.12em;
}

/* Divider. */
.bar-divider {
  width: 3px;
  background: currentColor;
  border: 0;
  margin: 0;
}

/* Fillable field — the "Your team for ▮Earned Media" device, static form. */
.field {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
  border-bottom: 2px solid currentColor;
  padding: 2px 7px 3px;
}
.field__value { font-family: "instrument-serif", "Instrument Serif Local", Georgia, serif; }

/* ========================== ROTATING FIELD ===========================
   The guide's "dynamic horizontal field element within service statements":
   a serif lead-in, then a ruled slot whose value cycles, with the outgoing
   value ghosted in the line above as it rises out. Pure CSS, no JS.

   Every service is real text in the DOM, so screen readers and crawlers get
   the full list even though only one shows at a time.

   --line is the ONE remaining sizing variable. The @keyframes below need a
   single source for the step distance, and keyframes cannot be redeclared per
   breakpoint without duplicating the whole block. It is always a literal px. */

.service-statement {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 3px 16px;
  font-size: 36px;
  line-height: 1.15;
}
.service-statement__lead {
  font-family: "instrument-serif", "Instrument Serif Local", Georgia, serif;
}

.field--rotating {
  --line: 42px;          /* one row of the cycling list */
  display: inline-block;
  border: 0;
  padding: 0;
}
.field__viewport {
  display: block;
  height: 84px;          /* --line × 2: ghost row above + active row */
  max-width: 100%;       /* the widest value sets the width — never let it bleed */
  overflow: hidden;
  border-bottom: 3px solid currentColor;
  /* Fades the outgoing value as it rises, rather than clipping it hard. */
  -webkit-mask-image: linear-gradient(to bottom, transparent 4%, rgba(0,0,0,.20) 40%, #000 70%);
          mask-image: linear-gradient(to bottom, transparent 4%, rgba(0,0,0,.20) 40%, #000 70%);
}
.field__list {
  display: block;
  margin: 0;
  padding: 0;
  padding-top: 42px;     /* = --line, seats the first value in the lower slot */
  list-style: none;
  animation: field-rotate 13.6s infinite;
}
.field__item {
  display: block;
  height: 42px;          /* = --line */
  line-height: 42px;
  font-family: "aileron", "Aileron Local", system-ui, sans-serif;
  font-weight: 400;
  white-space: nowrap;
}

@media (max-width: 900px) {
  .service-statement { font-size: 31px; }
  .field--rotating { --line: 36px; }
  .field__viewport { height: 72px; }    /* 36 × 2 */
  .field__list { padding-top: 36px; }
  .field__item { height: 36px; line-height: 36px; }
}
/* Narrow: values must stay on one line for the step animation to line up, so
   drop the type size and stack the lead-in rather than overflowing. */
@media (max-width: 600px) {
  .service-statement { display: block; font-size: 20px; }
  .service-statement__lead { display: block; margin-bottom: 8px; }
  .field--rotating { display: block; --line: 26px; }
  .field__viewport { height: 52px; }    /* 26 × 2 */
  .field__list { padding-top: 26px; }
  .field__item { height: 26px; line-height: 26px; }
}

/* Eight values, each taking 1.7s of the 13.6s loop: 1.0s held still, then a
   0.7s slide (the 7.35% offset inside each 12.5% step). The ninth item is a
   clone of the first so the loop restarts with no visible jump. */
@keyframes field-rotate {
  0%,     7.35% { transform: translateY(0); }
  12.5%, 19.85% { transform: translateY(calc(-1 * var(--line))); }
  25.0%, 32.35% { transform: translateY(calc(-2 * var(--line))); }
  37.5%, 44.85% { transform: translateY(calc(-3 * var(--line))); }
  50.0%, 57.35% { transform: translateY(calc(-4 * var(--line))); }
  62.5%, 69.85% { transform: translateY(calc(-5 * var(--line))); }
  75.0%, 82.35% { transform: translateY(calc(-6 * var(--line))); }
  87.5%, 94.85% { transform: translateY(calc(-7 * var(--line))); }
  100%          { transform: translateY(calc(-8 * var(--line))); }
}

/* Reduced motion: stop cycling and lay the services out as a grid of ruled
   fields, so no service becomes unreachable. */
@media (prefers-reduced-motion: reduce) {
  .service-statement { display: block; font-size: 36px; }
  .service-statement__lead { display: block; margin-bottom: 12px; }
  .field--rotating { display: block; }
  .field__viewport {
    height: auto;
    overflow: visible;
    border-bottom: 0;
    -webkit-mask-image: none;
            mask-image: none;
  }
  .field__list {
    animation: none;
    padding-top: 0;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
    gap: 12px 32px;
    max-width: 992px;
  }
  .field__item {
    height: auto;
    line-height: 1.25;
    white-space: normal;          /* nowrap would overflow the grid column */
    border-bottom: 2px solid currentColor;
    padding-bottom: 6px;
  }
  .field__item--clone { display: none; }
}

/* ========================= SOFTENED GEOMETRY ========================== */

.block { border-radius: 24px; }

/* Selected-corner rounding, as in the guide's stepped diagrams. */
.block--tl  { border-radius: 40px 0 0 0; }
.block--tr  { border-radius: 0 40px 0 0; }
.block--top { border-radius: 40px 40px 0 0; }

.media {
  border-radius: 24px;
  overflow: hidden;
  background: #eceae4;
}

/* Wireframe image placeholder — remove once real photography lands. */
.media--placeholder {
  display: grid;
  place-items: center;
  aspect-ratio: 4 / 3;
  color: #9c9a95;
  font-family: "aileron", "Aileron Local", system-ui, sans-serif;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 1px;
  text-transform: uppercase;
  background-image: linear-gradient(
    135deg,
    rgba(39,39,39,.06) 25%, transparent 25%,
    transparent 50%, rgba(39,39,39,.06) 50%,
    rgba(39,39,39,.06) 75%, transparent 75%
  );
  background-size: 14px 14px;
}

/* ============================== BUTTONS ===============================
   Aileron Bold. Outline versions are reserved for buttons/hashtags and use
   charcoal or white only — never a secondary colour. */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 15px 29px;
  border: 2px solid currentColor;
  /* 12px, not the pill this used to be, and not .media's literal 24px either:
     the button is only 52px tall, so a 24px radius renders as a full pill and
     would look unchanged. 12px is the value that actually reads as the same
     softened-rectangle family as the photo blocks — and it is proportionally
     what 24px is on a 96px-tall box. On the brand scale (6 · 12 · 24 · 40). */
  border-radius: 12px;
  background: transparent;
  color: inherit;
  font-family: "aileron", "Aileron Local", system-ui, sans-serif;
  font-weight: 700;
  font-size: 18px;
  line-height: 1;
  text-decoration: none;
  cursor: pointer;
  transition: background   240ms cubic-bezier(0.22, 0.61, 0.36, 1),
              border-color 240ms cubic-bezier(0.22, 0.61, 0.36, 1),
              color        240ms cubic-bezier(0.22, 0.61, 0.36, 1);
}
.btn--solid {
  border-color: var(--sl-ink);
  background: var(--sl-ink);
  color: var(--sl-cream);
}
/* Hover: butter fill, ink label. The border stays ink — butter and cream are
   near-identical in luminance (1.05:1), so without it the button's edge would
   all but vanish on the cream sections. focus-visible matches hover so
   keyboard users get the same feedback. */
:is(.btn--solid:hover, .btn--solid:focus-visible) {
  background: var(--sl-butter);
  color: var(--sl-ink);
}

@media (max-width: 600px) {
  .btn { padding: 13px 24px; font-size: 16px; }
}

/* ============================= SCRIBBLES ==============================
   Emphasis on key words inside body copy — not decoration. Charcoal on light,
   white on dark. Never yellow (unreadable on white). */
/* Underline marks: painted as a background on an *inline* box, so the phrase
   wraps with the rest of the sentence. As an inline-block it was atomic —
   whenever it did not fit in what was left of the line the whole phrase
   dropped to the next one and left a short ragged line above it (reported on
   Android, 26 Aug 2026). box-decoration-break redraws the mark under every
   fragment of a phrase that does break across lines. */
.scribble:not(.scribble--circled) {
  background-image: var(--scribble-mark);
  background-repeat: no-repeat;
  background-position: left bottom;
  background-size: 100% 0.42em;
  padding-bottom: 0.27em;
  -webkit-box-decoration-break: clone;
          box-decoration-break: clone;
}
.scribble--line   { --scribble-mark:      url(../assets/scribbles/line-underline.svg);
                    --scribble-mark-dark: url(../assets/scribbles/line-underline-cream.svg); }
.scribble--arc    { --scribble-mark:      url(../assets/scribbles/arc-underline.svg);
                    --scribble-mark-dark: url(../assets/scribbles/arc-underline-cream.svg); }
.scribble--wave   { --scribble-mark:      url(../assets/scribbles/wave-underline.svg);
                    --scribble-mark-dark: url(../assets/scribbles/wave-underline-cream.svg); }
.scribble--zigzag { --scribble-mark:      url(../assets/scribbles/zigzag-underline.svg);
                    --scribble-mark-dark: url(../assets/scribbles/zigzag-underline-cream.svg); }

/* Ring marks: wrap the phrase instead of underlining it, so they stay an
   atomic inline-block with the artwork positioned over it — a ring drawn
   across a line break reads as a mistake. */
.scribble--circled {
  position: relative;
  display: inline-block;
  white-space: nowrap;
}
.scribble--circled > :is(svg, img) {
  position: absolute;
  top: -0.28em;
  left: -0.5em;
  width: calc(100% + 1em);
  height: calc(100% + 0.56em);
  color: currentColor;
  pointer-events: none;
}

/* Dark grounds. An external SVG — whether loaded through <img> or as a
   background-image — is a separate document: its fill cannot inherit the
   page's colour. The guide requires these to read cream on dark, so the
   underlines swap to a cream-filled copy of the artwork, and the marks that
   are still <img> elements are inverted instead (exact — they're monochrome
   black). Regenerate the copies with:
     sed 's/fill="currentColor"/fill="#f9f8f4"/' x-underline.svg > x-underline-cream.svg */
:is(.section--ink, .section--teal) .scribble:not(.scribble--circled) {
  background-image: var(--scribble-mark-dark);
}
:is(.section--ink, .section--teal) :is(.scribble--circled > img, .scribble-inline) {
  filter: invert(1);
}

/* Standalone directional mark — sits in the text flow rather than over a
   phrase. For arrows used as pointers, not for emphasis underlines. */
.scribble-inline {
  display: inline-block;
  width: 52px;
  height: auto;
  margin-right: 12px;
  vertical-align: 0.12em;
  color: currentColor;
}

/* =========================== ACCESSIBILITY ============================ */

:where(a, button, [tabindex]):focus-visible {
  outline: 3px solid var(--sl-ink);
  outline-offset: 3px;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}
