/* FlockFactor v12. Two blocks: one screen, then the close.
   Paper, ink, two typefaces, no pictures. The work is a bar of wordmarks at the foot of the
   first screen. Colour is spent only where something can be clicked. */

/* ---------------------------------------------------------------- fonts */

@font-face {
  font-family: 'Bodoni';
  font-style: normal;
  font-weight: 400 900;
  font-display: swap;
  src: url(../assets/fonts/bodoni-latin.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 {
  /* instanced at opsz 28 / wght 500 and subset to the letters it sets: 7 KB for two words */
  font-family: 'Bodoni Italic';
  font-style: italic;
  font-weight: 500;
  font-display: swap;
  src: url(../assets/fonts/bodoni-italic-word.woff2) format('woff2');
}

@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-display: swap;
  src: url(../assets/fonts/archivo-latin.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: 'Archivo';
  font-style: normal;
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-display: swap;
  src: url(../assets/fonts/archivo-latin-ext.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 {
  --paper: #f0ebe0;
  --band:  #e2d9c5;
  --ink:   #17140f;
  --ink-2: #4a453b;
  --mute:  #877f70;
  --rule:  #d9d1c0;
  --red:   #8e3a1b;

  --serif-it: 'Bodoni Italic', 'Didot', 'Bodoni MT', Georgia, serif;
  --serif: 'Bodoni', 'Didot', 'Bodoni MT', Georgia, 'Times New Roman', serif;
  --sans:  'Archivo', 'Helvetica Neue', Arial, system-ui, sans-serif;

  --out: cubic-bezier(.22, 1, .36, 1);
  --t-1: 200ms;
  --t-2: 460ms;
  --t-3: 860ms;

  --gut: clamp(22px, 5vw, 92px);
  --max: 1560px;
  --head-h: 74px;
}

/* ------------------------------------------------------------- baseline */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--head-h) + 20px);
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.6;
  font-variation-settings: 'wght' 400, 'wdth' 100;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

/* paper tooth: fixed, behind all content, never over a letterform */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: .042;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.86' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 180px 180px;
}
main { position: relative; z-index: 1; }

[hidden] { display: none !important; }
::selection { background: var(--ink); color: var(--paper); }
a { color: inherit; }

:focus-visible {
  outline: 1.5px solid var(--red);
  outline-offset: 4px;
  border-radius: 1px;
}

/* --------------------------------------------------------------- header */

.head {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 50;
  height: var(--head-h);
  background: var(--paper);
  border-bottom: 1px solid transparent;
  transition: border-color var(--t-2) var(--out);
}
.head.is-stuck { border-bottom-color: var(--rule); }

.head__in {
  max-width: var(--max);
  height: 100%;
  margin: 0 auto;
  padding: 0 var(--gut);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
}

.mark {
  display: inline-flex;
  align-items: center;
  gap: 11px;
  font-size: 12.5px;
  letter-spacing: .26em;
  text-transform: uppercase;
  font-variation-settings: 'wght' 600, 'wdth' 100;
  text-decoration: none;
  white-space: nowrap;
}

/* Three birds rising in formation, tapering with distance: the lead one is the heaviest
   stroke and carries the accent. Stroke weights are per bird, so the flock keeps its depth
   at 22 px as well as blown up. */
.mark__fig {
  width: 22px;
  height: 13px;
  flex: none;
  overflow: visible;
  fill: none;
  stroke: var(--ink);
  stroke-linecap: square;
  stroke-linejoin: miter;
}
.mark__fig path:nth-child(1) { stroke-width: 1.5; }
.mark__fig path:nth-child(2) { stroke-width: 1.85; }
.mark__fig path:nth-child(3) { stroke-width: 2.25; stroke: var(--red); }

.mark__w b { font-variation-settings: 'wght' 680, 'wdth' 102; font-weight: inherit; }
.mark__w { font-variation-settings: 'wght' 380, 'wdth' 102; }

.head__do {
  position: relative;
  font-size: 13px;
  text-decoration: none;
  color: var(--ink-2);
  padding-bottom: 4px;
  white-space: nowrap;
  transition: color var(--t-1) var(--out);
}
.head__do::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: 0 50%;
  transition: transform var(--t-2) var(--out);
}
@media (hover: hover) and (pointer: fine) {
  .head__do:hover { color: var(--ink); }
  .head__do:hover::after { transform: scaleX(1); }
}
.head__do:focus-visible::after { transform: scaleX(1); }

/* ----------------------------------------------------------------- hero */

.hero {
  position: relative;
  max-width: var(--max);
  margin: 0 auto;
  padding: calc(var(--head-h) + clamp(20px, 3.2vh, 52px)) var(--gut) clamp(18px, 2.6vh, 34px);
  min-height: 100svh;
  display: flex;
  flex-direction: column;
}

.hero__h em,

.bar { position: relative; z-index: 1; }

.hero__h {
  margin: 0;
  font-family: var(--serif);
  font-weight: 500;
  font-variation-settings: 'opsz' 28;
  font-size: clamp(2.05rem, 8.8vw, 8.4rem);
  line-height: .96;
  letter-spacing: -.011em;
}

/* the block centres in whatever room is left above the bar, so a tall window opens the
   margins rather than opening a hole under the copy */
/* a title page: the headline holds the left eight columns and the offer sits beside its first
   line, so the top band is fully used and only one clean band of space is left before the bar */
/* On a tall window the slack is split two to one, above the title and below it, by two flex
   spacers that carry no height of their own. Auto margins would split it evenly and open a hole
   in the middle; a fixed gap would push the hero past one screen on a 900 px laptop. */
.hero::before { content: ''; display: block; flex: 2 1 0; }
.hero__gap { display: block; flex: 1 1 0; }

.hero__set {
  position: relative;
  z-index: 1;
  margin: 0;
  padding: clamp(4px, 0.8vh, 16px) 0;
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  column-gap: clamp(20px, 3vw, 56px);
  align-items: start;
}

.hero__h { grid-column: 1 / -1; grid-row: 1; }

/* the tagline and the action hang off one rule that runs the whole measure, so nothing in the
   hero is floating on its own any more */
.hero__row {
  grid-column: 1 / -1;
  grid-row: 2;
  margin-top: clamp(20px, 3vh, 44px);
  padding-top: clamp(14px, 1.8vh, 24px);
  border-top: 1px solid var(--plate-rule);
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 20px clamp(24px, 4vw, 64px);
  flex-wrap: wrap;
}

.hero__tag {
  margin: 0;
  font-size: clamp(1rem, 1.28vw, 1.24rem);
  line-height: 1.35;
  color: color-mix(in srgb, var(--plate-ink) 88%, transparent);
  font-variation-settings: 'wght' 420, 'wdth' 100;
}

/* ------------------------------------------------------------- the link */

.go {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 11px;
  text-decoration: none;
  font-size: 14.5px;
  font-variation-settings: 'wght' 520;
  padding-bottom: 8px;
  color: var(--ink);
  border: 0;
  background: none;
  font-family: inherit;
  cursor: pointer;
}
.go::before {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: var(--ink);
  transition: background var(--t-2) var(--out);
}
.go__arw {
  width: 6px;
  height: 6px;
  border-right: 1.2px solid currentColor;
  border-top: 1.2px solid currentColor;
  transform: rotate(45deg);
  transition: transform var(--t-2) var(--out);
}
@media (hover: hover) and (pointer: fine) {
  .go:hover { color: var(--red); }
  .go:hover::before { background: var(--red); }
  .go:hover .go__arw { transform: rotate(45deg) translate(3px, -3px); }
}
.go:focus-visible .go__arw { transform: rotate(45deg) translate(3px, -3px); }

/* ------------------------------------------------------------ the trust bar
   Full bleed at the foot of the first screen. Three identical sets travel left by exactly one
   set, so the loop has no seam. Pointing at it stops it, which is what makes a moving name
   clickable; where there is no pointer it does not move at all and the bar is swiped instead. */

.bar {
  position: relative;
  width: 100vw;
  margin-left: calc(50% - 50vw);
  padding-top: clamp(26px, 4.4vh, 62px);
}

.bar__ln {
  display: block;
  height: 1px;
  background: var(--rule);
  transform-origin: 0 50%;
}
.js-ready .bar__ln { transform: scaleX(0); }
.bar.in .bar__ln {
  transform: scaleX(1);
  transition: transform 1200ms var(--out);
}
.bar.in .bar__ln--bot { transition-delay: 90ms; }

.bar__win {
  overflow: hidden;

  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 7%, #000 93%, transparent 100%);
          mask-image: linear-gradient(90deg, transparent 0, #000 7%, #000 93%, transparent 100%);
}

.bar__track {
  display: flex;
  width: max-content;
  animation: marq 46s linear infinite;
  animation-delay: -7s;
}

@keyframes marq {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-33.3333%, 0, 0); }
}

/* the bar carries the work itself: each plate is that site's own first screen, and the whole
   thing is a door. Plate width is tied to viewport height so the band stays in proportion on a
   short laptop instead of pushing the hero past one screen. */
.bar__set {
  display: flex;
  align-items: flex-start;
  gap: var(--w-gap);
  padding: clamp(16px, 2.2vh, 26px) calc(var(--w-gap) / 2);
}

.w {
  display: block;
  width: var(--w-plate);
  flex: none;
  text-decoration: none;
  color: inherit;
}

.w__plate {
  display: block;
  position: relative;
  overflow: hidden;
  border-radius: 2px;
  background: #0d0b09;
  box-shadow: 0 0 0 1px var(--plate-rule), 0 18px 34px -22px rgba(0, 0, 0, .9);
  transition: box-shadow var(--t-2) var(--out), transform var(--t-2) var(--out);
}
.w__plate img {
  display: block;
  width: 100%;
  height: auto;
  transition: opacity var(--t-2) var(--out);
  opacity: .94;
}

.w__name {
  display: block;
  margin-top: 12px;
  font-family: var(--serif);
  font-weight: 500;
  font-variation-settings: 'opsz' 14;
  font-size: clamp(.98rem, 1.28vw, 1.18rem);
  line-height: 1.2;
  letter-spacing: -.012em;
  color: color-mix(in srgb, var(--plate-ink) 84%, transparent);
  transition: color var(--t-2) var(--out);
}

@media (hover: hover) and (pointer: fine) {
  .w:hover .w__plate {
    transform: translateY(-4px);
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--plate-ink) 34%, transparent),
                0 26px 44px -20px rgba(0, 0, 0, .95);
  }
  .w:hover .w__plate img { opacity: 1; }
  .w:hover .w__name { color: var(--ember); }
}
.w:focus-visible .w__name { color: var(--ember); }

/* a rule that draws under the name being pointed at */
  position: relative;
  display: inline-block;
  padding-bottom: .12em;
}
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: 0 50%;
  transition: transform var(--t-2) var(--out);
}

@media (hover: hover) and (pointer: fine) {
}
/* the bar keeps running under the pointer by request. Focus still stops it, so a keyboard can
   still reach a name that is not moving. */
.bar:focus-within .bar__track { animation-play-state: paused; }

/* no pointer means no way to stop it, so it does not start: the bar is swiped instead */
@media (hover: none), (pointer: coarse) {
  .bar__win {
    overflow-x: auto;
    overscroll-behavior-x: contain;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .bar__win::-webkit-scrollbar { display: none; }
  .bar__track { animation: none; }
  .bar__set:not(:first-child) { display: none; }
}

/* ------------------------------------------------------------- the form */

.form {
  grid-column: 2;
  display: grid;
  gap: 30px;
  align-content: start;
}

.field label {
  display: block;
  font-size: 11px;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--ink-2);
  font-variation-settings: 'wght' 560;
  margin-bottom: 12px;
}
.field input,
.field textarea {
  width: 100%;
  background: none;
  border: 0;
  border-bottom: 1px solid var(--rule);
  color: var(--ink);
  font-family: inherit;
  font-size: 16.5px;
  line-height: 1.5;
  padding: 6px 0 12px;
  border-radius: 0;
  transition: border-color var(--t-2) var(--out);
}
.field textarea { resize: vertical; min-height: 62px; }
.field input:focus,
.field textarea:focus { outline: none; border-bottom-color: var(--ink); }
.field.is-bad input,
.field.is-bad textarea { border-bottom-color: var(--red); }

.field__bad {
  margin: 10px 0 0;
  font-size: 13px;
  color: var(--red);
}

.form__go {
  display: flex;
  align-items: center;
  gap: 26px;
  flex-wrap: wrap;
  margin-top: 2px;
}
.form__note {
  margin: 0;
  font-size: 13px;
  color: var(--ink-2);
  max-width: 32ch;
}
.form__said {
  margin: 0;
  padding-top: 20px;
  border-top: 1px solid var(--rule);
  font-size: 15px;
  color: var(--ink-2);
}


/* ---------------------------------------------------------------- the ask
   Beginning a project opens a dialog rather than sending the visitor down the page. The form
   lives in the document either way: with scripting off the dialog is forced open as a panel
   under the hero and the Begin a project links are plain anchors to it. */

.modal {
  width: min(92vw, 660px);
  max-height: min(86vh, 760px);
  padding: 0;
  border: 0;
  border-radius: 3px;
  color: var(--ink);
  /* The panel is the one flat surface left, so it gets a sheet: the same pigment as the hero,
     desaturated and composited onto the panel colour itself at 16 percent, plus the page's own
     grain over it. The wash is opaque and its ground IS the panel colour, so wherever it sits no
     edge can show. Backgrounds do not move with the panel's scroll. */
  background-color: var(--paper);
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.86' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)' opacity='0.05'/%3E%3C/svg%3E"),
    url(../assets/img/wash.webp);
  background-size: 180px 180px, 560px auto;
  background-position: 0 0, 146% -40%;
  background-repeat: repeat, no-repeat;
  box-shadow: 0 42px 90px -34px rgba(0, 0, 0, .78);
  overflow: auto;
  overscroll-behavior: contain;
}
.modal::backdrop {
  background: rgba(8, 7, 6, .86);
  backdrop-filter: saturate(70%) blur(3px);
}

.modal[open] { animation: modal-in 340ms var(--out) both; }
.modal[open]::backdrop { animation: backdrop-in 340ms var(--out) both; }
@keyframes modal-in {
  from { opacity: 0; transform: translateY(12px) scale(.986); }
}
@keyframes backdrop-in { from { opacity: 0; } }

.modal__in { padding: clamp(30px, 5vw, 54px); }

.modal__h {
  margin: 0;
  font-family: var(--serif);
  font-weight: 500;
  font-variation-settings: 'opsz' 28;
  font-size: clamp(1.9rem, 4.6vw, 2.7rem);
  line-height: 1.0;
  letter-spacing: -.011em;
}
.modal__h em {
  font-family: var(--serif-it);
  font-style: italic;
  font-weight: 500;
  font-variation-settings: normal;
  letter-spacing: 0;
  padding-right: .04em;
  color: var(--red);
}

.modal__say {
  margin: clamp(14px, 2vh, 20px) 0 0;
  max-width: 42ch;
  font-size: 15.5px;
  line-height: 1.62;
  color: var(--ink-2);
}

.modal .form {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(22px, 3vh, 30px);
  margin-top: clamp(26px, 4vh, 38px);
}
.modal .field,
.modal .form__go,
.modal .form__said { grid-column: 1; }

/* the close control: its own method=dialog form, so it works before any script runs */
.modal__x { position: sticky; top: 0; height: 0; z-index: 1; }
.modal__x button {
  position: absolute;
  top: clamp(14px, 2.4vw, 22px);
  right: clamp(14px, 2.4vw, 22px);
  width: 34px;
  height: 34px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  color: var(--mute);
  cursor: pointer;
  transition: color var(--t-1) var(--out);
}
.modal__x button span,
.modal__x button span::after {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 15px;
  height: 1.5px;
  background: currentColor;
}
.modal__x button span { transform: translate(-50%, -50%) rotate(45deg); }
.modal__x button span::after { content: ''; top: 0; left: 0; transform: rotate(-90deg); }
@media (hover: hover) and (pointer: fine) {
  .modal__x button:hover { color: var(--ink); }
}

/* no scripting: the dialog is a panel under the hero instead of a window over it */
html:not(.js-ready) .modal {
  display: block;
  position: static;
  width: auto;
  max-width: none;
  max-height: none;
  border-radius: 0;
  box-shadow: none;
  overflow: visible;
}
html:not(.js-ready) .modal__x { display: none; }
html:not(.js-ready) .modal__in {
  max-width: var(--max);
  margin: 0 auto;
  padding: clamp(52px, 9vh, 120px) var(--gut);
}
html:not(.js-ready) .modal .form { max-width: 640px; }

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

.ln {
  display: block;
  overflow: hidden;
  /* deep enough for the italic descender. Bodoni's italic y and j swing a long way below the
     baseline, and the mask crops their tails at anything shallower. Measured, not guessed. */
  padding-bottom: .36em;
  margin-bottom: -.36em;
}
.ln > span { display: block; }

.js-ready .ln > span { transform: translateY(122%); }
.js-ready .lift { opacity: 0; transform: translateY(20px); }

.js-go .hero__h .ln > span {
  transform: none;
  transition: transform 1050ms var(--out);
}
.js-go .hero__h .ln:nth-child(2) > span { transition-delay: 95ms; }
.js-go .hero__h .ln:nth-child(3) > span { transition-delay: 190ms; }
.js-go .hero__h .ln:nth-child(4) > span { transition-delay: 285ms; }

.js-ready .lift.in {
  opacity: 1;
  transform: none;
  transition: opacity var(--t-3) var(--out), transform var(--t-3) var(--out);
}
.lift--d1.in { transition-delay:  70ms; }
.lift--d3.in { transition-delay: 210ms; }
.lift--d4.in { transition-delay: 280ms; }
.lift--d5.in { transition-delay: 350ms; }

/* the net: whatever happened to the script, the page is readable */
.js-net .bar__ln { transform: none; }
.js-net .lift {
  opacity: 1;
  transform: none;
  transition: opacity 420ms var(--out);
}
.js-net .ln > span {
  transform: none;
  transition: transform 620ms var(--out);
}

/* ============================================================== the first screen
   The hero is a plate: warm ink, full bleed, the sentence reversed out of it, and the client
   band a shade lifted inside the same darkness. The page returns to paper at the close, so the
   ink reads as a printed cover rather than as a dark theme. */

:root {
  --plate:      #141210;
  --plate-2:    #1d1a16;
  --plate-ink:  #f1ece1;
  --plate-mute: rgba(241, 236, 225, .70);
  --plate-rule: rgba(241, 236, 225, .19);
  --ember:      #f0ac7c;
  --w-plate:    clamp(200px, 23vh, 350px);
  --glow-top:   -30%;
  --glow-right: -14vw;
  --glow-w:     min(92vw, 1420px);
  --glow-op:    .34;
  --glow-rot:   -4deg;
  --w-gap:      clamp(20px, 2.4vw, 44px);
}

.hero {
  isolation: isolate;
  max-width: none;
  padding-left: max(var(--gut), calc(50vw - var(--max) / 2 + var(--gut)));
  padding-right: max(var(--gut), calc(50vw - var(--max) / 2 + var(--gut)));
  background: var(--plate);
  color: var(--plate-ink);
}
.hero__end { display: block; height: 1px; margin-top: -1px; }

.hero__h em { color: var(--ember); }

.hero .go { color: var(--plate-ink); }
.hero .go::before { background: var(--plate-ink); }
@media (hover: hover) and (pointer: fine) {
  .hero .go:hover { color: var(--ember); }
  .hero .go:hover::before { background: var(--ember); }
}

/* the band sits outside the masked window, or the edge fade would feather its colour into the
   plate and put a soft edge back on the page */
.bar__band { background: var(--plate-2); }
.bar__ln { background: var(--plate-rule); }
.hero :focus-visible { outline-color: var(--ember); }

/* The splash. Real pigment, premultiplied onto black and drawn with mix-blend-mode screen, so
   black contributes nothing and the mark has no edge anywhere: dense pigment reads as light, thin
   pigment falls into the plate. The bleed box is exactly the viewport wide so the only place it is
   ever cut is the window edge. */
.hero__glow {
  position: absolute;
  z-index: 0;
  top: 0;
  left: calc(50% - 50vw);
  width: 100vw;
  height: 100%;
  overflow: hidden;
  pointer-events: none;
  mix-blend-mode: screen;
  opacity: var(--glow-op);
}
.hero__glow img {
  position: absolute;
  top: var(--glow-top);
  right: var(--glow-right);
  width: var(--glow-w);
  height: auto;
  transform: rotate(var(--glow-rot));
  transform-origin: 100% 0;
}

/* Two layers of noise give the plate a surface. The coarse one, at a very low frequency and a
   1400 px tile, mottles the ink the way light falls unevenly across heavy board; the fine one
   over it is the grain. Both are procedural, so they cost no request and cannot band. */
.hero__ground {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: .13;
  mix-blend-mode: screen;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1400' height='1400'%3E%3Cfilter id='m'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.004' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3CfeComponentTransfer%3E%3CfeFuncR type='linear' slope='0.30' intercept='-0.13'/%3E%3CfeFuncG type='linear' slope='0.30' intercept='-0.13'/%3E%3CfeFuncB type='linear' slope='0.30' intercept='-0.13'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Crect width='1400' height='1400' filter='url(%23m)'/%3E%3C/svg%3E");
  background-size: 1400px 1400px;
  background-position: 62% 28%;
}

/* the grain reads as film on the plate, so it is allowed a little more presence there */
.hero::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: .065;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.86' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)' fill='%23fff'/%3E%3C/svg%3E");
  background-size: 180px 180px;
}

/* The header reverses out onto the plate while the first screen is under it, and is paper
   everywhere else. Paper is the default, so with scripting off it is a legible bar rather than
   cream type on cream paper further down. */
.head.is-plate {
  background: transparent;
  color: var(--plate-ink);
  border-bottom-color: transparent;
}
.head.is-plate .mark__fig { stroke: var(--plate-ink); }
.head.is-plate .mark__fig path:nth-child(3) { stroke: var(--ember); }
.head.is-plate .head__do { color: var(--plate-mute); }
@media (hover: hover) and (pointer: fine) {
  .head.is-plate .head__do:hover { color: var(--plate-ink); }
}
.head.is-plate .head__do::after { background: currentColor; }

/* ----------------------------------------------------------- responsive */

/* short laptops: the first screen holds the headline, the offer and the bar or it holds nothing */
@media (min-width: 861px) and (max-height: 830px) {
  .hero { padding-top: calc(var(--head-h) + 22px); padding-bottom: 18px; }
  .hero__h { font-size: min(7vw, 5.8rem); }
    .bar { padding-top: 22px; }
  :root { --w-plate: clamp(180px, 21vh, 300px); }
}

@media (max-width: 860px) {
  :root { --head-h: 64px; }

  .hero { min-height: 100svh; }

  /* on a phone the sweep crosses the empty top of the plate rather than sitting off screen */
  :root {
    --glow-top:   -4%;
    --glow-right: -34vw;
    --glow-w:     186vw;
    --glow-op:    .38;
    --glow-rot:   -6deg;
  }

  /* the title page stacks: headline, then the offer, then the action */
  .hero__set { grid-template-columns: minmax(0, 1fr); }
  .hero__h { grid-column: 1; grid-row: 1; }
    grid-column: 1;
    grid-row: 2;
    margin-top: clamp(26px, 4.4vh, 48px);
  }
    .hero .go {
    grid-column: 1;
    grid-row: 3;
    justify-self: start;
    margin-top: clamp(22px, 3.4vh, 40px);
  }
  }

@media (max-width: 560px) {
  body { font-size: 16px; }
    }

/* ------------------------------------------------------ reduced motion */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
  .js-ready .ln > span,
  .js-ready .lift,
  .js-ready .bar__ln { opacity: 1 !important; transform: none !important; }

  .bar__track { animation: none !important; transform: none !important; }
  .bar__win { overflow-x: auto; }
  .bar__set:not(:first-child) { display: none; }
}
