/* Spoil — spoil.agency
   The prototype runtime is gone; these rules carry what it did:
   the style-hover attributes, the 860px breakpoint, focus and selection. */

:root {
  --font-sans: "Archivo", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --font-script: "Imperial Script", cursive;
  --font-mono: "Fragment Mono", ui-monospace, "SF Mono", Menlo, monospace;
  /* Measured height of the sticky header, which the hero subtracts from the
     viewport so that header + hero is exactly one screen. It was hard-coded at
     62px and was wrong at both breakpoints — the header is 69px on desktop and
     80px on a phone — so the hero ran 7px long on desktop and 18px long on a
     phone, which is what pushed the Apply button under the browser chrome.
     One value, two places; keep it in step with the header's own padding. */
  --hdr: 69px;
  --sat: env(safe-area-inset-top, 0px);   /* read back by the ?herodebug overlay */
  --sab: env(safe-area-inset-bottom, 0px);
}

/* The root background is what iOS paints in the areas OUTSIDE the layout
   viewport: overscroll, and the strip behind Safari's collapsed tab bar and
   home indicator that no web content can reach (see README, "What iOS Safari
   actually allows"). While the hero is the content at the bottom of the
   viewport, hero.js flips this to the hero's own black so that strip reads as
   the hero continuing to the edge of the glass. */
html { background: #ffffff; }
body { margin: 0; background: #ffffff; -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; }

/* iOS draws a large play glyph on a <video autoplay> whose autoplay the
   DEVICE refused — Low Power Mode, Low Data Mode, the Auto-Play setting. The
   poster is the clip's own frame 0 and the first tap starts it, so the glyph
   adds nothing but a button in the middle of the hero. */
[data-hero-video]::-webkit-media-controls-start-playback-button,
[data-hero-video]::-webkit-media-controls {
  display: none !important;
  -webkit-appearance: none;
}
a { color: inherit; text-decoration: none; }
a:hover { color: #f92143; }
::selection { background: #f92143; color: #ffffff; }
:focus-visible { outline: 1px solid #0a0a0a; outline-offset: 2px; }
img { max-width: 100%; }
input::placeholder, textarea::placeholder { color: #b5b5b5; }
input:disabled { background: #f4f4f4; color: #8a8a8a; cursor: not-allowed; }
input, textarea, select, button { font-family: var(--font-sans); }
input:focus, textarea:focus, select:focus { outline: none; border-color: #0a0a0a; }

/* The single breakpoint. */
@media (max-width: 860px) {
  :root { --hdr: calc(80px + env(safe-area-inset-top, 0px)); }
  /* Measured on the device (iPhone 16 Pro Max, iOS 26): 100lvh is 836 on a
     956pt screen whose status bar is 62 — so Safari renders the page 58pt past
     lvh, under the collapsed tab bar, and a hero sized to 100lvh stops short of
     the bottom of the screen. 120px overshot (pushed the next section down);
     0 fell short. 60px is the measured strip. The copy is padded up by the
     same amount so nothing visible moves. */
  :root { --bleed: 60px; }
  /* The strip under Safari's tab bar on iOS 26 is painted from the page's
     extended background (html blended with body) — and so is the strip behind
     the status bar, from the same single colour. Darkening it made the bottom
     read as the hero continuing to the glass, and made the status-bar area
     black above the white header. The call was white at both ends; nothing
     else on the page reaches either strip (theme-color, color-scheme and the
     hero's own height were all tried). See README. */
  [data-dt] { display: none !important; }
  [data-stack] { grid-template-columns: 1fr !important; }
  [data-stack2] { grid-template-columns: 1fr 1fr !important; }
  [data-rowwrap] { flex-direction: column !important; align-items: flex-start !important; }
  /* Hero on a phone: the subject sits high in every frame, the scrim inverts so
     the copy has a floor to sit on, and the copy is pushed below the fold line. */
  [data-hero-img] { object-position: 50% 0% !important; }
  /* The scrim used to run 86–94% black across the bottom third, which made the
     picture vanish exactly where it is now supposed to reach the screen edge —
     the hero read as "stops half way down" whatever the layout did. It now
     holds a legible floor behind the copy and lets the picture through. The
     paragraph keeps its text-shadow; the headline gets one below. */
  [data-hero-scrim] {
    background: linear-gradient(0deg, rgba(0,0,0,0.66) 0%, rgba(0,0,0,0.6) 36%,
      rgba(0,0,0,0.42) 56%, rgba(0,0,0,0.14) 76%, rgba(0,0,0,0) 100%) !important;
  }
  [data-hero-head] { text-shadow: 0 2px 28px rgba(0,0,0,0.5); }
  [data-hero-head], [data-hero-cap-item] { will-change: opacity; }
  /* The hero fills the phone edge to edge, and the copy stays off the chrome.
     Two different heights are doing two different jobs:

       100lvh  the screen with the browser chrome retracted — the full glass.
               The section is this tall, so the stills, the clips and the scrim
               (all inset:0 on the section) run underneath Safari's address bar
               and home indicator instead of stopping short of them.
       100svh  the screen with the chrome showing — the guaranteed-visible box.
               The copy is padded up to sit inside this, so the headline, the
               paragraph and the Apply button are never behind the chrome.

     calc(100lvh - 100svh) is exactly the height of that chrome, which is what
     the copy has to clear. On desktop all three units are equal, so this is a
     no-op there. */
  [data-hero] {
    height: calc(100vh - var(--hdr) + var(--bleed)) !important;    /* iOS < 15.4: vh is the large viewport */
    height: calc(100lvh - var(--hdr) + var(--bleed)) !important;
    min-height: 0 !important;
  }
  [data-hero-copy] {
    /* Was 58svh, which was the whole problem. The section is
       align-items: flex-end, so this padding never moved the copy anywhere —
       the block is transparent and already sits against the bottom edge. Its
       only effect was to make the block taller than the section's min-height,
       growing the hero to 943px inside an 874px viewport and carrying the CTA
       off the bottom of the screen, under the browser chrome. */
    padding-top: clamp(40px, 8svh, 120px) !important;
    padding-bottom: calc(clamp(28px, 6vw, 44px) +
      env(safe-area-inset-bottom, 0px) + (100lvh - 100svh) + var(--bleed)) !important;
  }
  [data-hero-cap] { top: 14px !important; }
}

/* viewport-fit=cover lets the hero run to the physical edge of the screen; the
   price is that everything else has to be told where the unsafe zones are.
   env() is 0 wherever there is no inset, so these are no-ops on desktop. */
header {
  padding-top: calc(18px + env(safe-area-inset-top, 0px)) !important;
}
footer {
  padding-bottom: env(safe-area-inset-bottom, 0px) !important;
}
/* Short phones (SE-class, and anything in landscape) have no room for the
   breathing space above the copy — spend it on keeping the hero one screen. */
@media (max-width: 860px) and (max-height: 640px) {
  [data-hero-copy] { padding-top: 24px !important; }
  /* Below this height the approved headline, paragraph, CTA and status line are
     together taller than the screen, and the copy is bottom-aligned — so a fixed
     height would crop the headline off the top. Let the hero grow instead and
     cost a short scroll, which is the lesser of the two. */
  [data-hero] {
    height: auto !important;
    min-height: calc(100vh - var(--hdr) + var(--bleed)) !important;
    min-height: calc(100lvh - var(--hdr) + var(--bleed)) !important;
  }
}

/* Role rows get cramped between the breakpoint and ~1080px: the meta columns
   drop under the title rather than squeezing it. */
@media (min-width: 861px) and (max-width: 1080px) {
  [data-rolerow] { grid-template-columns: 1fr auto !important; }
  [data-rolerow] span:nth-of-type(2),
  [data-rolerow] span:nth-of-type(3) { grid-column: 1 / -1; }
}
@media (min-width: 861px) {
  [data-mb] { display: none !important; }
  [data-logo-img] { height: 27px !important; }
  [data-logo-script] { font-size: 25px !important; }
}

/* Hover states — one accent, never decorative. */
.btn-ink:hover { background: #f92143; color: #ffffff; }
/* The hero CTA is white on the dark frame and goes to the accent on hover. */
.btn-invert:hover { background: #f92143; color: #ffffff; }
.hero-quiet:hover { color: #ffffff; }
/* 404 — outlined pill fills to ink. */
.btn-outline:hover { background: #0d0d0d; color: #ffffff; border-color: #0d0d0d; }
.footer-link:hover { color: #ffffff; }
.lockup:hover, .lockup:hover span { color: inherit; }
.rule-link:hover { color: #f92143; border-color: #f92143; }
.row-link:hover { color: #f92143; }
.ghost-btn:hover { color: #f92143; }
.cc-option:hover { background: #f5f5f5; }

/* Menu — the one place anything moves. */
.menu-panel {
  position: fixed; inset: 0; background: #0d0d0d; z-index: 60;
  display: flex; flex-direction: column;
  padding: 118px clamp(20px, 5vw, 64px) 36px; box-sizing: border-box;
  visibility: hidden; transform: translateX(100%);
  transition: transform 0.6s cubic-bezier(0.32, 0.72, 0, 1), visibility 0.6s;
}
.menu-panel nav {
  display: flex; flex-direction: column; gap: 28px;
  opacity: 0; transform: translateY(16px);
  transition: opacity 0.45s cubic-bezier(0.32, 0.72, 0, 1) 0.12s,
              transform 0.55s cubic-bezier(0.32, 0.72, 0, 1) 0.12s;
}
.menu-chrome {
  position: fixed; top: 0; left: 0; right: 0; z-index: 70;
  display: flex; justify-content: space-between; align-items: center;
  padding: 18px clamp(20px, 5vw, 64px); box-sizing: border-box;
  pointer-events: none; visibility: hidden; transition: visibility 0.6s;
}
.menu-chrome .lockup { pointer-events: auto; position: relative; display: flex; align-items: flex-end; gap: 9px; }
.menu-mark-ink, .menu-mark-white { display: flex; align-items: flex-end; gap: 9px; transition: opacity 0.45s ease 0.1s; }
.menu-mark-white { position: absolute; inset: 0; opacity: 0; }
.menu-mark-ink { opacity: 1; }

body.menu-open { overflow: hidden; }
body.menu-open .menu-panel { visibility: visible; transform: translateX(0%); }
body.menu-open .menu-panel nav { opacity: 1; transform: translateY(0px); }
body.menu-open .menu-chrome { visibility: visible; }
body.menu-open .menu-mark-ink { opacity: 0; }
body.menu-open .menu-mark-white { opacity: 1; }

/* Close button — two lines that become an X in place. */
.menu-close {
  pointer-events: auto; position: relative; background: none; border: none;
  width: 44px; height: 44px; cursor: pointer; padding: 0; margin-right: -11px;
}
.menu-close span {
  position: absolute; height: 1.5px; display: block; transform-origin: center;
  background: #0a0a0a;
  transition: transform 0.5s cubic-bezier(0.22, 1, 0.36, 1) 0.05s,
              width 0.5s cubic-bezier(0.22, 1, 0.36, 1) 0.05s,
              left 0.5s cubic-bezier(0.22, 1, 0.36, 1) 0.05s,
              background 0.4s ease 0.22s;
}
.menu-close .line-1 { top: 17px; left: 11px; width: 22px; }
.menu-close .line-2 { top: 25.5px; left: 18px; width: 15px; }
body.menu-open .menu-close span {
  background: #ffffff;
  transition: transform 0.5s cubic-bezier(0.22, 1, 0.36, 1) 0.12s,
              width 0.5s cubic-bezier(0.22, 1, 0.36, 1) 0.12s,
              left 0.5s cubic-bezier(0.22, 1, 0.36, 1) 0.12s,
              background 0.15s ease 0.02s;
}
body.menu-open .menu-close .line-1 { transform: translateY(4.25px) rotate(45deg); }
body.menu-open .menu-close .line-2 { left: 11px; width: 22px; transform: translateY(-4.25px) rotate(-45deg); }

/* Motion elsewhere: near zero. Honor the setting. */
@media (prefers-reduced-motion: reduce) {
  .menu-panel, .menu-panel nav, .menu-chrome,
  .menu-mark-ink, .menu-mark-white, .menu-close span { transition: none !important; }
  html { scroll-behavior: auto !important; }
}

/* Form chrome shared by both applications. */
.field-input, .field-select, .field-textarea {
  font: 400 15px/1.4 var(--font-sans); color: #0a0a0a; background: #ffffff;
  border: 1px solid #d9d9d9; border-radius: 999px; padding: 13px 22px;
  box-sizing: border-box; width: 100%;
}
.field-textarea { font-size: 15px; line-height: 1.6; border-radius: 22px; padding: 16px 22px; resize: vertical; }
.field-select {
  appearance: none; -webkit-appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'><path d='M1 1l4 4 4-4' fill='none' stroke='%230a0a0a'/></svg>");
  background-repeat: no-repeat; background-position: right 20px center;
}
.chip {
  font: 400 13px/1 var(--font-sans); padding: 12px 22px; border-radius: 999px;
  border: 1px solid #d9d9d9; background: #ffffff; color: #0a0a0a; cursor: pointer;
}
.chip[aria-pressed="true"] { font-weight: 500; border-color: #0d0d0d; background: #0d0d0d; color: #ffffff; }
.box { width: 18px; height: 18px; border-radius: 5px; border: 1px solid #d9d9d9; background: #ffffff; flex: none; display: flex; align-items: center; justify-content: center; color: transparent; font: 400 11px/1 var(--font-sans); }
.box-lg { width: 20px; height: 20px; border-radius: 6px; font-size: 12px; }
[aria-pressed="true"] > .box { border-color: #0d0d0d; background: #0d0d0d; color: #ffffff; }
.err { font: 400 12px/1.5 var(--font-sans); color: #f92143; }
.hint { font: 400 12px/1.5 var(--font-sans); color: #8a8a8a; }
.hidden { display: none !important; }

/* Safe-area insets for the menu — after its own padding shorthand, or the
   shorthand wins the cascade and the panel runs under the status bar. */
.menu-chrome { padding-top: calc(18px + env(safe-area-inset-top, 0px)); }
.menu-panel {
  padding-top: calc(118px + env(safe-area-inset-top, 0px));
  padding-bottom: calc(36px + env(safe-area-inset-bottom, 0px));
}
