/*
Theme Name: Deadlift Digital
Theme URI: https://deadliftdigitalllc.com/
Author: Deadlift Digital LLC
Description: Company site for Deadlift Digital LLC. Iron-and-chalk industrial design with a forged-orange accent, self-hosted type, and a locally generated chalk-dust hero. A roster that grows as apps ship, the entity details that show the company is real, and the four legal pages an app publisher needs. Company details are edited in Appearance → Customize → Deadlift Digital, not in code.
Version: 1.0.0
Requires at least: 6.0
Tested up to: 6.7
Requires PHP: 7.4
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: deadlift-digital
Tags: one-column, custom-colors, custom-menu, editor-style, full-width-template
*/

/* ==========================================================================
   Deadlift Digital — iron & chalk

   Cast iron and gunmetal for the room, chalk for the type, and one forged
   orange that only ever marks the thing you are meant to press. The accent is
   rationed on purpose: spend it on more than the CTA, the plate rule and hover
   and it stops reading as heat.

   Dark only, deliberately. A gym at 5am is not a light-mode room, and a second
   palette would double the surface area for no gain on a six-page site.

   Type is a condensed heavy display against a plain grotesque — the contrast
   between them is the design, so the middle of the scale is left empty.
   ========================================================================== */

/* Self-hosted, so the site makes no third-party request on any page load.
   That is faster than a font CDN and one fewer disclosure for the privacy
   policy. Latin subset only; the fallback stack covers anything outside it. */
@font-face {
  font-family: "Anton";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("assets/fonts/anton-400-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: "Inter";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("assets/fonts/inter-400-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: "Inter";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("assets/fonts/inter-600-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: "IBM Plex Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("assets/fonts/ibm-plex-mono-400-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: "IBM Plex Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("assets/fonts/ibm-plex-mono-500-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;
}

:root {
  /* Surfaces, darkest to lightest. */
  --iron:        #0A0A0B;
  --gunmetal:    #16181C;
  --raised:      #1E2128;
  --raised-2:    #272B33;

  /* Ink. Chalk is the page's white; it is warm so it never reads as LCD. */
  --chalk:       #E8E4DA;
  --chalk-2:     #A8A79F;
  --chalk-faint: #6E6E68;

  /* The one accent. Forged orange — hot steel, not safety cone. */
  --heat:        #D94A1F;
  --heat-bright: #F2662F;
  --heat-deep:   #A33413;
  --on-heat:     #0A0A0B;

  /* Structure */
  --line:        #2A2E36;
  --line-strong: #3C424C;

  --measure:     72ch;
  --gutter:      clamp(1.25rem, 5vw, 4rem);
  --shell:       1240px;

  /* Vertical rhythm. Sections breathe or the whole thing reads as a template. */
  --band:        clamp(5.5rem, 12vw, 10.5rem);

  --font-display: "Anton", "Arial Narrow", "Haettenschweiler", sans-serif;
  --font-body:    "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --font-mono:    "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  --ease: cubic-bezier(0.2, 0.7, 0.2, 1);
}

/* --------------------------------------------------------------------------
   Reset — narrow on purpose. A theme drops into someone else's WordPress and
   should not fight the admin bar or the block editor's own resets.
   -------------------------------------------------------------------------- */

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

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

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}

body {
  margin: 0;
  background: var(--iron);
  color: var(--chalk);
  font-family: var(--font-body);
  font-size: 1.0625rem;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  /* clip, not hidden. `overflow-x: hidden` forces the used value of overflow-y
     to `auto`, which makes body its own scroll container — and a scroll-driven
     `scroll(root)` timeline then reports 0% however far the page is scrolled,
     so the progress bar never moves. `clip` suppresses the horizontal axis
     without creating a scroll container. The hidden line below it is the
     fallback for engines without `clip`, which also predate scroll timelines. */
  overflow-x: hidden;
  overflow-x: clip;
}

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

a { color: var(--chalk); text-decoration-color: var(--line-strong); text-underline-offset: 0.25em; }
a:hover { color: var(--heat-bright); text-decoration-color: currentColor; }

:focus-visible {
  outline: 2px solid var(--heat-bright);
  outline-offset: 3px;
}

::selection { background: var(--heat); color: var(--on-heat); }

/* --------------------------------------------------------------------------
   Grain and scroll progress.

   The grain is what stops large flat dark areas reading as a cheap background.
   It is 5% opacity — you should not be able to see it, only notice its
   absence. The progress bar is scroll-driven CSS, so it costs no JS.
   -------------------------------------------------------------------------- */

body::after {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 99;
  opacity: 0.05;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* Scroll-driven, so it tracks real scroll position with no JS and no
   main-thread work. Hidden outright where the feature is unsupported rather
   than shimmed — a progress bar is not worth a scroll listener. */
.scroll-progress {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  background: var(--heat);
  transform-origin: 0 50%;
  transform: scaleX(0);
  z-index: 70;
  pointer-events: none;
  animation: ddl-progress linear both;
  animation-timeline: scroll(root block);
}
@keyframes ddl-progress { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@supports not (animation-timeline: scroll()) {
  .scroll-progress { display: none; }
}
.admin-bar .scroll-progress { top: 32px; }
@media (max-width: 782px) { .admin-bar .scroll-progress { top: 46px; } }
@media (prefers-reduced-motion: reduce) { .scroll-progress { display: none; } }

/* --------------------------------------------------------------------------
   Type scale. The contrast between the display and the body is the design;
   keep the middle of the scale empty so the jump stays a jump.
   -------------------------------------------------------------------------- */

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 400;
  line-height: 0.92;
  letter-spacing: 0.005em;
  text-transform: uppercase;
  margin: 0 0 0.5em;
}

h1 { font-size: clamp(2.75rem, 9.5vw, 7.5rem); }
h2 { font-size: clamp(2rem, 5.2vw, 3.9rem); }
h3 { font-size: clamp(1.3rem, 2.4vw, 1.85rem); line-height: 1.02; }
h4 { font-size: 1.0625rem; letter-spacing: 0.06em; }

p { margin: 0 0 1.15em; max-width: var(--measure); }

strong { color: #FFF; font-weight: 600; }

.lede {
  font-size: clamp(1.1rem, 1.9vw, 1.375rem);
  line-height: 1.55;
  color: var(--chalk-2);
  max-width: 62ch;
}

/* Section eyebrow: "01 / APPS". The mono numeral is the industrial cue. */
.eyebrow {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--chalk-faint);
  display: flex;
  align-items: center;
  gap: 0.85rem;
  margin: 0 0 1.75rem;
}
.eyebrow::after {
  content: "";
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, var(--line-strong), transparent);
}
.eyebrow b { color: var(--heat); font-weight: 500; }

/* Section numerals, set large and hollow.
 *
 * Scoped to .band so it only catches the numbered front-page sections — the
 * legal pages put the word "Legal" in the same slot, and a 3.5rem outlined
 * "Legal" is a different thing entirely.
 *
 * The numeral keeps its own line-height and a nudge off the baseline so the
 * mono label sits optically centred against it rather than on its feet.
 */
.band > .shell > .eyebrow,
.band .shell > .eyebrow {
  align-items: center;
  gap: 1.15rem;
  margin-bottom: clamp(2rem, 4vw, 3rem);
}

.band .eyebrow b {
  font-family: var(--font-display);
  font-size: clamp(2.25rem, 5.5vw, 3.75rem);
  line-height: 0.8;
  letter-spacing: -0.02em;
  color: transparent;
  -webkit-text-stroke: 1.5px var(--line-strong);
  text-stroke: 1.5px var(--line-strong);
  transform: translateY(-0.02em);
  transition: -webkit-text-stroke-color 0.4s var(--ease);
}

/* Warm on hover, so the numeral is doing something rather than just being big.
   (A sibling selector cannot key this off the section's reveal state — the
   eyebrow precedes the revealed content in the DOM, so `~` never matches.) */
.band:hover .eyebrow b { -webkit-text-stroke-color: var(--heat-deep); }

/* --------------------------------------------------------------------------
   Shell
   -------------------------------------------------------------------------- */

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

.band { padding-block: var(--band); position: relative; }
.band--tight { padding-block: calc(var(--band) * 0.62); }
.band--hair { border-top: 1px solid var(--line); }

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--heat);
  color: var(--on-heat);
  padding: 0.75rem 1.25rem;
  font-family: var(--font-mono);
  font-size: 0.8rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  z-index: 999;
}
.skip-link:focus { left: 0; }

/* --------------------------------------------------------------------------
   Textures

   Knurling: the crosshatch on a barbell shaft. Kept at a whisper — at full
   strength it vibrates against text and looks like a broken background.
   -------------------------------------------------------------------------- */

.knurl::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0.4;
  background-image:
    repeating-linear-gradient(45deg,  rgba(232,228,218,0.035) 0 1px, transparent 1px 7px),
    repeating-linear-gradient(-45deg, rgba(232,228,218,0.035) 0 1px, transparent 1px 7px);
}

/* The plate rule: bars of falling width, like plates loaded on a bar. */
.plate-rule {
  display: flex;
  align-items: center;
  gap: 4px;
  margin: 0;
  padding: 0;
  border: 0;
  height: 10px;
}
.plate-rule i {
  display: block;
  width: 7px;
  background: var(--line-strong);
}
.plate-rule i:nth-child(1) { height: 10px; background: var(--heat); }
.plate-rule i:nth-child(2) { height: 9px; }
.plate-rule i:nth-child(3) { height: 7px; }
.plate-rule i:nth-child(4) { height: 5px; }
.plate-rule i:nth-child(5) { height: 3px; }
.plate-rule::after {
  content: "";
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, var(--line-strong), transparent);
}

/* --------------------------------------------------------------------------
   Header
   -------------------------------------------------------------------------- */

.site-header {
  position: sticky;
  top: 0;
  z-index: 60;
  background: color-mix(in srgb, var(--iron) 88%, transparent);
  backdrop-filter: blur(14px) saturate(1.2);
  -webkit-backdrop-filter: blur(14px) saturate(1.2);
  border-bottom: 1px solid transparent;
  transition: border-color 0.3s var(--ease), background 0.3s var(--ease);
}
.site-header.is-stuck {
  border-bottom-color: var(--line);
  background: color-mix(in srgb, var(--iron) 96%, transparent);
}
.admin-bar .site-header { top: 32px; }
@media (max-width: 782px) { .admin-bar .site-header { top: 46px; } }

.masthead {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  min-height: 78px;
}

/* Wordmark: a bar-and-plate glyph plus the name, set tight. */
.wordmark {
  display: inline-flex;
  align-items: center;
  gap: 0.7rem;
  text-decoration: none;
  color: var(--chalk);
  flex-shrink: 0;
}
.wordmark:hover { color: var(--chalk); }
.wordmark:hover .wordmark__bar .plate { fill: var(--heat-bright); }

/* The barbell mark, loaded the way a bar is actually loaded: heavy plates
   inboard against the collar, light ones outside them. The accent rides the
   heavy pair, so the eye lands on the mass rather than on the ends. */
.wordmark__bar { width: 34px; height: 22px; flex: none; overflow: visible; }
.wordmark__bar .shaft    { fill: var(--chalk-2); }
.wordmark__bar .plate    { fill: var(--heat); transition: fill 0.25s var(--ease); }
.wordmark__bar .plate-sm { fill: var(--chalk-faint); }

.wordmark__text {
  font-family: var(--font-display);
  font-size: 1.15rem;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  line-height: 1;
  white-space: nowrap;
}
.wordmark__text em {
  font-style: normal;
  color: var(--chalk-faint);
}

/* Nav */
.nav { display: flex; align-items: center; gap: 2rem; }
.nav ul {
  display: flex;
  align-items: center;
  gap: 2rem;
  list-style: none;
  margin: 0;
  padding: 0;
}
.nav a {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--chalk-2);
  text-decoration: none;
  position: relative;
  padding-block: 0.4rem;
}
.nav a::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  width: 0; height: 2px;
  background: var(--heat);
  transition: width 0.28s var(--ease);
}
.nav a:hover { color: var(--chalk); }
.nav a:hover::after, .nav .current-menu-item > a::after { width: 100%; }

.nav-toggle {
  display: none;
  background: none;
  border: 1px solid var(--line-strong);
  color: var(--chalk);
  width: 44px; height: 40px;
  cursor: pointer;
  align-items: center;
  justify-content: center;
  padding: 0;
}
.nav-toggle span {
  display: block;
  width: 18px; height: 1.5px;
  background: currentColor;
  position: relative;
}
.nav-toggle span::before, .nav-toggle span::after {
  content: ""; position: absolute; left: 0;
  width: 18px; height: 1.5px; background: currentColor;
  transition: transform 0.25s var(--ease);
}
.nav-toggle span::before { top: -6px; }
.nav-toggle span::after  { top: 6px; }
.nav-toggle[aria-expanded="true"] span { background: transparent; }
.nav-toggle[aria-expanded="true"] span::before { transform: translateY(6px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span::after  { transform: translateY(-6px) rotate(-45deg); }

@media (max-width: 860px) {
  .nav-toggle { display: inline-flex; }
  .nav {
    position: fixed;
    inset: 78px 0 auto 0;
    background: var(--gunmetal);
    border-bottom: 1px solid var(--line);
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: 0.5rem var(--gutter) 1.75rem;
    transform: translateY(-140%);
    transition: transform 0.35s var(--ease);
    max-height: calc(100vh - 78px);
    overflow-y: auto;
  }
  .nav.is-open { transform: translateY(0); }
  .nav ul { flex-direction: column; align-items: stretch; gap: 0; width: 100%; }
  .nav li { border-bottom: 1px solid var(--line); }
  .nav a { display: block; padding: 1.15rem 0; font-size: 0.9rem; }
  .nav a::after { display: none; }
  .nav .btn { margin-top: 1.5rem; text-align: center; }
}

/* --------------------------------------------------------------------------
   Buttons
   -------------------------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  padding: 0.95rem 1.7rem;
  font-family: var(--font-mono);
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  text-decoration: none;
  border: 1px solid transparent;
  cursor: pointer;
  transition: background 0.22s var(--ease), color 0.22s var(--ease),
              border-color 0.22s var(--ease), transform 0.22s var(--ease);
  white-space: nowrap;
}
.btn:active { transform: translateY(1px); }

.btn--heat { background: var(--heat); color: var(--on-heat); }
.btn--heat:hover { background: var(--heat-bright); color: var(--on-heat); }

.btn--ghost { border-color: var(--line-strong); color: var(--chalk); }
.btn--ghost:hover { border-color: var(--chalk); color: var(--chalk); background: rgba(232,228,218,0.04); }

.btn__arrow { transition: transform 0.22s var(--ease); }
.btn:hover .btn__arrow { transform: translateX(4px); }

/* --------------------------------------------------------------------------
   Hero
   -------------------------------------------------------------------------- */

.hero {
  position: relative;
  min-height: clamp(560px, 86vh, 900px);
  display: flex;
  align-items: flex-end;
  overflow: hidden;
  border-bottom: 1px solid var(--line);
}

.hero__media {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  background: var(--iron);
}
.hero__media video, .hero__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* The clip is already a dark room — it does not need to be dimmed into a
     grey smudge as well. Desaturating it was throwing away the one warm
     thing in the frame, which is the whole reason the shot works. */
  opacity: 0.82;
  filter: contrast(1.06) saturate(0.92);
}

/* Two scrims, each with one job.
   1. A diagonal that weights the bottom-left corner, where the headline sits,
      and lets the light and the dust column stay open to the upper right.
   2. A floor and a ceiling, so the sticky header has something to sit on and
      the join into the next section is not a hard edge. */
.hero__media::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(to top right,
      rgba(10,10,11,0.95) 0%,
      rgba(10,10,11,0.74) 26%,
      rgba(10,10,11,0.20) 58%,
      rgba(10,10,11,0.34) 100%),
    linear-gradient(180deg,
      rgba(10,10,11,0.82) 0%,
      rgba(10,10,11,0.00) 26%,
      rgba(10,10,11,0.00) 54%,
      rgba(10,10,11,0.86) 100%);
}

.hero__inner {
  position: relative;
  z-index: 2;
  width: 100%;
  padding-block: clamp(3rem, 9vh, 6rem) clamp(3rem, 8vh, 5.5rem);
}

.hero h1 {
  margin: 0 0 1.4rem;
  max-width: 15ch;
}

/* Masked line wipe: each line sits in its own overflow-hidden box and rises
   into it, so the letters appear from behind an invisible edge rather than
   fading in. The padding/negative-margin pair is not decoration — with
   line-height below 1 the descender on the g in "Digital" falls outside the
   line box and the mask would shear it off. */
.hero h1 .line {
  display: block;
  overflow: hidden;
  padding-bottom: 0.12em;
  margin-bottom: -0.12em;
}
.hero h1 .line > span {
  display: block;
  animation: ddl-wipe 0.95s var(--ease) 0.6s both;
}
.hero h1 .line:nth-child(2) > span { animation-delay: 0.7s; }

@keyframes ddl-wipe {
  from { transform: translateY(105%); }
  to   { transform: translateY(0); }
}

/* The rest of the hero follows the headline in, then stops. A hero that keeps
   moving after it has arrived is a hero you cannot read. */
.hero__meta,
.hero .lede,
.hero__actions { animation: ddl-rise 0.8s var(--ease) both; }
.hero__meta    { animation-delay: 0.52s; }
.hero .lede    { animation-delay: 0.86s; }
.hero__actions { animation-delay: 0.98s; }

/* --------------------------------------------------------------------------
   Load impact.

   The bar is already on the floor in frame one of the clip, so nothing here
   pretends to animate the bar itself — what lands is the camera. The frame
   drops in, overshoots into the floor, and rings out in a short decaying
   shake, with one bloom of dust light at the moment of contact. That is what
   a heavy set of plates hitting concrete actually feels like from across the
   room, and it costs three keyframe blocks and no JavaScript.

   Everything is `both`-filled and finite: the hero settles and then holds
   still, because a hero that keeps moving is a hero you cannot read.
   -------------------------------------------------------------------------- */

/* The bar really does fall in the intro clip, so nothing here fakes the drop —
   this is only the part a camera would feel. The bar contacts the floor on
   frame 13 of 90 at 24fps, so the shake and the dust bloom fire at 0.54s.
   Retime both if the intro is ever re-rendered. */
.hero { animation: ddl-impact 0.5s cubic-bezier(0.2, 0.7, 0.2, 1) 0.54s both; }

@keyframes ddl-impact {
  0%   { transform: translate(0, 0); }
  9%   { transform: translate(-2px, 6px); }
  23%  { transform: translate(3px, -4px); }
  39%  { transform: translate(-3px, 3px); }
  56%  { transform: translate(2px, -2px); }
  74%  { transform: translate(-1px, 1px); }
  100% { transform: translate(0, 0); }
}

/* One bloom of dust light on contact, gone almost immediately. */
.hero__flash {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: radial-gradient(60% 45% at 50% 78%, rgba(232,228,218,0.5) 0%, transparent 70%);
  opacity: 0;
  animation: ddl-dustbloom 0.9s var(--ease) 0.54s both;
}

@keyframes ddl-dustbloom {
  0%   { opacity: 0; transform: scale(0.9); }
  8%   { opacity: 1; transform: scale(1); }
  100% { opacity: 0; transform: scale(1.12); }
}

@media (prefers-reduced-motion: reduce) {
  .hero,
  .hero__flash { animation: none; }
  .hero__flash { display: none; }
  .hero__meta, .hero .lede, .hero__actions { animation-delay: 0s; }
}

@keyframes ddl-rise {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .hero h1 .line > span,
  .hero__meta,
  .hero .lede,
  .hero__actions { animation: none; }
}
/* "DIGITAL" drops to an outline so the two words read as one lockup with a
   change of material — solid plate, then chalk outline. */
.hero h1 .ghost {
  color: transparent;
  -webkit-text-stroke: 1.5px var(--chalk-faint);
  text-stroke: 1.5px var(--chalk-faint);
}

.hero__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem 1.5rem;
  margin-bottom: 1.5rem;
  font-family: var(--font-mono);
  font-size: 0.74rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--chalk-faint);
}
.hero__meta .dot { width: 5px; height: 5px; background: var(--heat); flex: none; }

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.85rem;
  margin-top: 2.25rem;
}

/* --------------------------------------------------------------------------
   Marquee

   Orange band, iron type, off-axis by a degree. It earns its place by
   carrying the entity facts, which is the one thing this site exists to
   state — a ticker of slogans would just be noise.

   The track holds the run twice so translating it -50% lands exactly on the
   start of the second copy and the loop has no seam.
   -------------------------------------------------------------------------- */

.marquee {
  position: relative;
  z-index: 1;
  overflow: hidden;
  background: var(--heat);
  padding: 0.95rem 0;
  transform: rotate(-1deg) scale(1.025);
  transform-origin: center;
  box-shadow: 0 10px 40px rgba(232, 93, 38, 0.18);
}

.marquee-track {
  display: flex;
  width: max-content;
  white-space: nowrap;
  animation: ddl-marquee 42s linear infinite;
}

.marquee-run {
  display: inline-flex;
  align-items: center;
  font-family: var(--font-display);
  font-size: clamp(0.9rem, 1.5vw, 1.15rem);
  letter-spacing: 0.01em;
  text-transform: uppercase;
  color: var(--on-heat);
}
.marquee-run > span { padding-inline: 1.1rem; }
/* The separator is a plate, not a bullet. */
.marquee-run > i {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--on-heat);
  opacity: 0.45;
  flex: none;
}

@keyframes ddl-marquee {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

.marquee:hover .marquee-track { animation-play-state: paused; }

@media (prefers-reduced-motion: reduce) {
  .marquee { transform: none; }
  .marquee-track { animation: none; }
}

/* --------------------------------------------------------------------------
   Statement band
   -------------------------------------------------------------------------- */

.statement-band {
  border-bottom: 1px solid var(--line);
  padding-block: clamp(4rem, 9vw, 7.5rem);
  position: relative;
  overflow: hidden;
  isolation: isolate;
}

/* A second generated clip — dust turning in a shaft of light — sits behind the
   statement. It is pushed much further down than the hero's: the hero can
   carry an image because the headline is enormous, but this line is ordinary
   display type and anything louder than a texture would start competing with
   it. Cool-toned on purpose, so the two clips read as different rooms. */
.statement-band__media {
  position: absolute;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  pointer-events: none;
}
.statement-band__media video,
.statement-band__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0.3;
}
.statement-band__media::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(to right, var(--iron) 0%, rgba(10,10,11,0.72) 46%, rgba(10,10,11,0.3) 100%),
    linear-gradient(180deg, var(--iron) 0%, rgba(10,10,11,0) 22%, rgba(10,10,11,0) 78%, var(--iron) 100%);
}

/* The two children stack: one reserves the final layout and never shows, the
   other does the scrambling on top. Without the reserved copy the whole band
   reflows on every frame as proportional glyphs swap widths. */
.statement {
  position: relative;
  font-size: clamp(1.7rem, 5vw, 4rem);
  line-height: 1.04;
  max-width: 19ch;
  margin: 0;
}
.statement__ghost { visibility: hidden; }
.statement__vis {
  position: absolute;
  inset: 0;
  display: block;
}
/* Mid-decode characters read as noise, so they are dimmed until resolved. */
.statement__vis .ch--scrambling { color: var(--chalk-faint); }

/* --------------------------------------------------------------------------
   App roster

   Built from a PHP array so a new app is a new array entry, not a new
   template. The "in development" card is a real state, not a placeholder —
   an empty-looking roster is worse than an honest one.
   -------------------------------------------------------------------------- */

.roster {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  gap: clamp(1rem, 2vw, 1.5rem);
}

.app-card {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--gunmetal);
  border: 1px solid var(--line);
  padding: clamp(1.6rem, 3vw, 2.4rem);
  overflow: hidden;
  transition: border-color 0.3s var(--ease), transform 0.3s var(--ease), background 0.3s var(--ease);
  min-height: 300px;
}
.app-card--live:hover {
  border-color: var(--line-strong);
  transform: translateY(-3px);
  background: var(--raised);
}
/* Heat bleeds in from the top edge on hover — the card "warms up". */
.app-card--live::before {
  content: "";
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 2px;
  background: var(--heat);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.4s var(--ease);
}
.app-card--live:hover::before { transform: scaleX(1); }

.app-card--soon { background: transparent; border-style: dashed; }

.app-card__top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 1.5rem;
}

.app-card__icon {
  width: 52px; height: 52px;
  border: 1px solid var(--line-strong);
  display: grid;
  place-items: center;
  flex: none;
  background: var(--iron);
}
/* An app icon fills its tile edge to edge, the way it does on a home screen.
   The plate mark fallback stays small and centred, because it is a mark, not
   an icon, and cropping it to the box would just look like a mistake. */
.app-card__icon img { width: 100%; height: 100%; object-fit: cover; }

.status {
  font-family: var(--font-mono);
  font-size: 0.66rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  padding: 0.35rem 0.6rem;
  border: 1px solid var(--line-strong);
  color: var(--chalk-faint);
  white-space: nowrap;
}
.status--live { color: var(--heat); border-color: color-mix(in srgb, var(--heat) 45%, transparent); }

.app-card h3 { margin-bottom: 0.5rem; }
.app-card__tag {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--chalk-faint);
  margin-bottom: 1rem;
  display: block;
}
.app-card p { color: var(--chalk-2); font-size: 0.97rem; flex: 1; }

.app-card__link {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  margin-top: 1.25rem;
  font-family: var(--font-mono);
  font-size: 0.78rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--chalk);
  text-decoration: none;
}
.app-card__link .btn__arrow { transition: transform 0.22s var(--ease); }
.app-card--live:hover .app-card__link { color: var(--heat-bright); }
.app-card--live:hover .app-card__link .btn__arrow { transform: translateX(4px); }

/* Whole card is the click target; the visible link stays for screen readers
   and for anyone who tabs. */
.app-card__stretch::after { content: ""; position: absolute; inset: 0; }

/* --------------------------------------------------------------------------
   Company / facts table — the "we are real" block
   -------------------------------------------------------------------------- */

.split {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  gap: clamp(2.5rem, 6vw, 5.5rem);
  align-items: start;
}
@media (max-width: 900px) { .split { grid-template-columns: 1fr; } }

.facts {
  border: 1px solid var(--line);
  background: var(--gunmetal);
  position: relative;
}
.facts__head {
  padding: 1.15rem 1.5rem;
  border-bottom: 1px solid var(--line);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--chalk-faint);
  display: flex;
  align-items: center;
  gap: 0.7rem;
}
.facts dl { margin: 0; }
/* Scoped to the rows inside the list. An unscoped `.facts div` also caught
   .facts__head and gave the panel title a two-column grid, which is why the
   bullet and the label were landing on separate lines. */
.facts dl > div {
  display: grid;
  grid-template-columns: 11rem 1fr;
  gap: 1rem;
  padding: 1rem 1.5rem;
  border-bottom: 1px solid var(--line);
}
.facts dl > div:last-child { border-bottom: 0; }
@media (max-width: 560px) { .facts dl > div { grid-template-columns: 1fr; gap: 0.25rem; } }

.facts dt {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--chalk-faint);
  padding-top: 0.15rem;
}
.facts dd { margin: 0; color: var(--chalk); font-size: 0.97rem; }
.facts dd a { color: var(--heat-bright); text-decoration: none; }
.facts dd a:hover { text-decoration: underline; }

/* --------------------------------------------------------------------------
   Contact
   -------------------------------------------------------------------------- */

.contact-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
}
.contact-card {
  background: var(--iron);
  padding: clamp(1.75rem, 3.5vw, 2.5rem);
}
.contact-card h4 {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.2em;
  color: var(--chalk-faint);
  margin-bottom: 1rem;
  text-transform: uppercase;
}
.contact-card a.big {
  font-family: var(--font-display);
  font-size: clamp(1.15rem, 2.1vw, 1.5rem);
  text-transform: uppercase;
  text-decoration: none;
  color: var(--chalk);
  line-height: 1.1;
  word-break: break-word;
}
.contact-card a.big:hover { color: var(--heat-bright); }
.contact-card p { font-size: 0.92rem; color: var(--chalk-faint); margin: 0.75rem 0 0; }
.contact-card address { font-style: normal; color: var(--chalk-2); font-size: 0.97rem; }

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

.site-footer {
  border-top: 1px solid var(--line);
  background: var(--gunmetal);
  position: relative;
}
/* An explicit first column plus repeat(auto-fit, …) lets the browser fit the
   three link columns beside a brand column that has already been squeezed to
   its minimum, so at tablet widths the columns overlap. Stack deliberately
   instead, and only go four-across when there is genuinely room. */
.footer-top {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(2rem, 5vw, 3rem);
  padding-block: clamp(3rem, 7vw, 4.5rem);
}
@media (min-width: 600px) {
  .footer-top { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .footer-brand { grid-column: 1 / -1; }
}
@media (min-width: 940px) {
  .footer-top {
    grid-template-columns: minmax(0, 1.6fr) repeat(3, minmax(0, 1fr));
    gap: clamp(2rem, 5vw, 4rem);
  }
  .footer-brand { grid-column: auto; }
}
.footer-brand p {
  color: var(--chalk-faint);
  font-size: 0.92rem;
  max-width: 34ch;
  margin-top: 1.25rem;
}
.footer-col h4 {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.2em;
  color: var(--chalk-faint);
  margin-bottom: 1.25rem;
}
.footer-col ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.7rem; }
.footer-col a {
  color: var(--chalk-2);
  text-decoration: none;
  font-size: 0.92rem;
  /* An email address is one long unbreakable token and will punch out of a
     narrow column otherwise. */
  overflow-wrap: anywhere;
}
.footer-col a:hover { color: var(--heat-bright); }

.footer-bottom {
  border-top: 1px solid var(--line);
  padding-block: 1.75rem;
  display: flex;
  flex-wrap: wrap;
  gap: 1rem 2rem;
  align-items: center;
  justify-content: space-between;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  color: var(--chalk-faint);
  text-transform: uppercase;
}

/* --------------------------------------------------------------------------
   Legal / long-form pages
   -------------------------------------------------------------------------- */

.page-head {
  border-bottom: 1px solid var(--line);
  padding-block: clamp(4rem, 10vw, 7rem) clamp(2rem, 5vw, 3.5rem);
  position: relative;
}
.page-head h1 { font-size: clamp(2.25rem, 6.5vw, 4.75rem); margin-bottom: 1rem; }
.page-head .updated {
  font-family: var(--font-mono);
  font-size: 0.74rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--chalk-faint);
}

.prose { max-width: 74ch; padding-block: clamp(3rem, 7vw, 5rem); }
.prose > * + * { margin-top: 1.15em; }
.prose h2 {
  font-size: clamp(1.4rem, 2.8vw, 2rem);
  margin-top: 2.75em;
  margin-bottom: 0.65em;
  padding-top: 1.5rem;
  border-top: 1px solid var(--line);
}
.prose h2:first-child { margin-top: 0; border-top: 0; padding-top: 0; }
.prose h3 {
  font-family: var(--font-body);
  font-weight: 600;
  text-transform: none;
  font-size: 1.05rem;
  letter-spacing: 0;
  line-height: 1.4;
  margin-top: 2em;
  margin-bottom: 0.5em;
  color: #FFF;
}
.prose p, .prose li { color: var(--chalk-2); }
.prose a { color: var(--heat-bright); }
.prose ul, .prose ol { padding-left: 1.3rem; }
.prose li { margin-bottom: 0.55em; }
.prose li::marker { color: var(--heat); }
.prose strong { color: var(--chalk); }

.prose table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.94rem;
  margin-block: 1.5em;
}
.prose th, .prose td {
  text-align: left;
  padding: 0.85rem 1rem;
  border: 1px solid var(--line);
  vertical-align: top;
}
.prose th {
  background: var(--gunmetal);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--chalk-faint);
  font-weight: 500;
}
.prose td { color: var(--chalk-2); }

/* A callout for the sentences a reader must not skim past. */
.note {
  border: 1px solid var(--line-strong);
  border-left: 3px solid var(--heat);
  background: var(--gunmetal);
  padding: 1.25rem 1.5rem;
  font-size: 0.95rem;
}
.note p:last-child { margin-bottom: 0; }
.note strong { color: #FFF; }

.toc {
  border: 1px solid var(--line);
  background: var(--gunmetal);
  padding: 1.5rem;
  margin-bottom: 2.5rem;
}
.toc h2 {
  border: 0; padding: 0; margin: 0 0 1rem;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.2em;
  color: var(--chalk-faint);
}
.toc ol { margin: 0; padding-left: 1.2rem; display: grid; gap: 0.5rem; }
.toc a { color: var(--chalk-2); text-decoration: none; font-size: 0.93rem; }
.toc a:hover { color: var(--heat-bright); }

/* --------------------------------------------------------------------------
   Reveal on scroll. Opt-in via JS adding .reveal-ready so that a visitor with
   JS off sees everything rather than a blank page.
   -------------------------------------------------------------------------- */

.reveal-ready .reveal {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 0.7s var(--ease), transform 0.7s var(--ease);
}
.reveal-ready .reveal.is-in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .reveal-ready .reveal { opacity: 1 !important; transform: none !important; }
}

/* --------------------------------------------------------------------------
   404
   -------------------------------------------------------------------------- */

.error-404 {
  position: relative;
  min-height: 68vh;
  display: grid;
  place-items: center;
  text-align: center;
  padding-block: var(--band);
  overflow: hidden;
  isolation: isolate;
}
/* A still rather than a clip. Nobody should be on this page long enough to
   justify the bytes of a video. */
.error-404__media {
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
}
.error-404__media img { width: 100%; height: 100%; object-fit: cover; opacity: 0.22; }
.error-404__media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(70% 60% at 50% 50%, rgba(10,10,11,0.55) 0%, var(--iron) 100%);
}
.error-404 .code {
  font-family: var(--font-display);
  font-size: clamp(5rem, 22vw, 16rem);
  line-height: 0.82;
  color: transparent;
  -webkit-text-stroke: 2px var(--line-strong);
  text-stroke: 2px var(--line-strong);
  margin-bottom: 1.5rem;
}
.error-404 p { margin-inline: auto; }

/* --------------------------------------------------------------------------
   WordPress housekeeping. Themes are rejected without these.
   -------------------------------------------------------------------------- */

.screen-reader-text {
  border: 0;
  clip: rect(1px, 1px, 1px, 1px);
  clip-path: inset(50%);
  height: 1px; width: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  position: absolute !important;
  word-wrap: normal !important;
}
.screen-reader-text:focus {
  background-color: var(--heat);
  clip: auto !important;
  clip-path: none;
  color: var(--on-heat);
  display: block;
  font-size: 0.875rem;
  height: auto;
  left: 5px; top: 5px;
  padding: 15px 23px 14px;
  text-decoration: none;
  width: auto;
  z-index: 100000;
}

/* An unfilled company fact. Loud by design — this marks the spot where a
   legal page is still missing a real answer, and a subtle version of it would
   defeat the entire point. */
.ddl-todo {
  background: var(--heat);
  color: var(--on-heat);
  font-family: var(--font-mono);
  font-size: 0.8em;
  font-weight: 500;
  padding: 0.15em 0.45em;
  letter-spacing: 0.02em;
}

.alignleft  { float: left;  margin-right: 1.5em; }
.alignright { float: right; margin-left: 1.5em; }
.aligncenter { display: block; margin-inline: auto; }
.wp-caption { max-width: 100%; }
.wp-caption-text { font-size: 0.85rem; color: var(--chalk-faint); }
.sticky, .gallery-caption, .bypostauthor { /* required by the theme check */ }
