/**
 * ARTHAGE — SAFE OVERRIDES
 *
 * This file is loaded after the captured production styles.
 * Put visual adjustments here instead of editing arthage-base.css directly.
 * Keep the root grid variables (--ch, --line, --cols, etc.) owned by the
 * responsive script unless you intentionally redesign the grid engine.
 */

/*
 * Self-hosted premium open-source fonts.
 * Body/editorial: Inter. System/navigation/ASCII: JetBrains Mono.
 * No Google import, no external font request, no captured ABC font dependency.
 */
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/assets/fonts/inter-400.woff2") format("woff2");
}
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("/assets/fonts/inter-500.woff2") format("woff2");
}
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("/assets/fonts/inter-600.woff2") format("woff2");
}
@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/assets/fonts/jetbrains-mono-400.woff2") format("woff2");
}
@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("/assets/fonts/jetbrains-mono-500.woff2") format("woff2");
}
@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("/assets/fonts/jetbrains-mono-600.woff2") format("woff2");
}

/* Brand tokens: safe to extend and reuse in the rules below. */
:root {
  --arthage-transition-fast: 180ms;
  --arthage-transition-smooth: 480ms cubic-bezier(0.22, 1, 0.36, 1);
  --arthage-font-mono:
    "JetBrains Mono", "SFMono-Regular", ui-monospace, "Cascadia Mono", Menlo,
    Consolas, monospace;
  --arthage-font-body: "Inter", "Helvetica Neue", Arial, sans-serif;
  /* Fast rollback path if the brand font direction changes again. */
  --arthage-font-alt-mono:
    "SFMono-Regular", ui-monospace, "Cascadia Mono", Menlo, Consolas, monospace;
  --arthage-font-alt-body:
    -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Arial,
    sans-serif;
}

html,
body,
body * {
  font-family: var(--arthage-font-body);
  /* Surgical crispness: optimizeLegibility + grayscale smoothing on every target. */
  font-smooth: always;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-kerning: normal;
  font-optical-sizing: auto;
  font-synthesis: none;
}

nav,
header,
footer,
button,
.btn,
.buttons,
.linelist,
.monocaps,
.ascii,
.worktitle,
.position,
.info,
.meta,
.contact,
.casefooter {
  font-family: var(--arthage-font-mono);
  font-variant-ligatures: none;
  font-feature-settings:
    "kern" 1,
    "liga" 0,
    "calt" 0;
  font-weight: 500;
}

/*
 * ARTHAGE — TYPE CRISPNESS & WEIGHT RESTORATION
 * The captured design drove weight through a variable-font "wght" axis. The new
 * static webfonts ignore that axis, which collapsed every weight to 400 and made
 * the type look soft. Neutralize the dead axis, restore real font-weights, and
 * finish remapping the last captured legacy families to the brand stack so the whole
 * page renders in one crisp type system. (Loaded Inter + JetBrains Mono weights:
 * 400 / 500 / 600.)
 */
* {
  font-variation-settings: normal !important;
}

html,
body {
  font-weight: 500;
}

b,
strong,
.fat,
.fat p,
.fat h1,
.fat h2,
.fat h3,
.fat li,
.fat a,
h1.fat,
h2.fat,
h3.fat,
p.fat,
li.fat,
a.fat {
  font-weight: 600;
}

.text,
.big,
.mega,
.fat {
  font-family: var(--arthage-font-body);
}

.mono,
.mega .pretext,
.number,
.year,
code,
pre {
  font-family: var(--arthage-font-mono);
}

/*
 * ARTHAGE — HARD FONT FAMILY OVERRIDES
 * The captured stylesheet still contains high-specificity selectors using
 * `abc`, `abcplus` and `mono`; one service-title selector even ships with
 * `!important`. Override only the family here. Do not change the captured grid
 * math, font-size, line-height or letter-spacing values.
 */
html,
body,
body
  :where(
    p,
    h1,
    h2,
    h3,
    h4,
    h5,
    h6,
    li,
    dt,
    dd,
    a,
    span,
    label,
    input,
    textarea
  ) {
  font-family: var(--arthage-font-body) !important;
}

nav,
nav *,
header,
header *,
footer,
footer *,
button,
a.button,
.btn,
.buttons,
.linelist,
.linelist *,
.monocaps,
.ascii,
.mono,
.mono *,
.mega .pretext,
.worktitle,
.worktitle *,
.position,
.position *,
.info,
.info *,
.meta,
.meta *,
.contact,
.contact *,
.casefooter,
.casefooter *,
.number,
.year,
code,
pre,
#side-dialog,
#side-dialog *,
.mobile-container .settings,
.case-grid .case-grid-item .info,
body.work .items .info,
body.journal-post .post-body code,
.admin-translation-lang,
.engine-label,
.engine-modules span,
.store-url,
#admin .texteditor textarea,
#admin .controls .mini input {
  font-family: var(--arthage-font-mono) !important;
}

body.about .arthage-about-square-media {
  aspect-ratio: 1 / 1;
  overflow: hidden;
}

body.about .arthage-about-square-media img {
  height: 100%;
  object-fit: cover;
  object-position: center;
  width: 100%;
}

/* Work index media discipline.
 * The project grid must stay scannable even when Sanity receives portrait,
 * landscape or oversized source files. Detail pages keep their own art
 * direction; this rule only normalizes the /work overview cards.
 */
body.work {
  --arthage-work-grid-ratio: 1 / 1;
  --arthage-work-grid-position: center;
}

body.work .gridcontainer .items .item {
  align-self: flex-start;
}

body.work .gridcontainer .items .project-preview {
  display: block;
  width: 100%;
}

body.work .gridcontainer .items .project-preview .image,
body.work .gridcontainer .items .project-preview .video {
  aspect-ratio: var(--arthage-work-grid-ratio);
  background: rgba(var(--black-rgb), 0.045);
  height: auto !important;
  max-height: none !important;
  overflow: hidden;
  width: 100%;
}

body.work .gridcontainer .items .project-preview .image img,
body.work .gridcontainer .items .project-preview .image video,
body.work .gridcontainer .items .project-preview .video img,
body.work .gridcontainer .items .project-preview .video video {
  height: 100% !important;
  max-height: none !important;
  object-fit: cover !important;
  object-position: var(--arthage-work-grid-position);
  width: 100% !important;
}

body.work .gridcontainer .items .project-preview .image canvas,
body.work .gridcontainer .items .project-preview .image .ascii,
body.work .gridcontainer .items .project-preview .video canvas,
body.work .gridcontainer .items .project-preview .video .ascii {
  height: 100% !important;
  width: 100% !important;
}

/* ASCII / PIXEL mode on the /work grid.
 * The renderer can't size an `object-fit: cover` element without a usable srcset
 * (videos are always excluded from that path), so the forced `cover` above makes
 * text/pixel conversion throw -> black grid. In those modes the media is hidden
 * and replaced by the ASCII canvas, so drop `cover` for the safe full-frame draw.
 * Specificity must beat the `object-fit: cover !important` rule above. */
html.textmode body.work .gridcontainer .items .project-preview .image img,
html.textmode body.work .gridcontainer .items .project-preview .image video,
html.textmode body.work .gridcontainer .items .project-preview .video img,
html.textmode body.work .gridcontainer .items .project-preview .video video,
html.pixelmode body.work .gridcontainer .items .project-preview .image img,
html.pixelmode body.work .gridcontainer .items .project-preview .image video,
html.pixelmode body.work .gridcontainer .items .project-preview .video img,
html.pixelmode body.work .gridcontainer .items .project-preview .video video {
  object-fit: fill !important;
}

@media (min-width: 769px) {
  body.work
    .gridcontainer
    .items
    .project-preview[data-project-slug="merrachi"] {
    --arthage-work-grid-position: center top;
  }

  body.work
    .gridcontainer
    .items
    .project-preview[data-project-slug="merrachi"][data-media-index="1"] {
    --arthage-work-grid-position: center 18%;
  }
}

@media (max-width: 768px) {
  body.work
    .gridcontainer
    .items
    .project-preview[data-project-slug="merrachi"] {
    --arthage-work-grid-position: center top;
  }

  body.work
    .gridcontainer
    .items
    .project-preview[data-project-slug="merrachi"][data-media-index="1"] {
    --arthage-work-grid-position: center 18%;
  }

  body.work .gridcontainer,
  body.work .gridcontainer .span-4,
  body.work .gridcontainer .items {
    max-width: 100% !important;
    width: 100% !important;
  }

  body.work .gridcontainer .items .case {
    box-sizing: border-box;
    padding-right: var(--char2) !important;
    width: 100% !important;
  }

  body.work .gridcontainer .items .item {
    flex-basis: calc((100% - var(--char2)) / 2) !important;
  }
}

.text h1,
.big p,
.big h1,
.big h2,
.big li,
.big a,
h2.big,
p.big,
li.big,
h1.big,
a.big,
.fat p,
.fat h1,
.fat h2,
.fat li,
.fat a,
h2.fat,
p.fat,
li.fat,
h1.fat,
a.fat,
.mega p,
.mega h1,
.mega h2,
.mega li,
.mega a,
p.mega,
h1.mega,
h2.mega,
li.mega,
a.mega,
:is(.col p, .col li, .col dt, .col dd, .col h2, .col h3):not(.mega):not(.big),
.contact-dialog .disclaimer,
.service h2,
#admin .controls input[type="text"],
#admin .controls input[type="number"],
#admin .controls label.file,
#admin .controls button.edit {
  font-family: var(--arthage-font-body) !important;
}

.contact-dialog .headline,
#side-dialog .contact-dialog .headline,
#side-dialog .contact-dialog p.headline {
  font-family: var(--arthage-font-body) !important;
  font-smooth: always;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

nav,
nav *,
header,
header *,
footer,
footer *,
.linelist,
.linelist *,
.mono,
.mono *,
.worktitle,
.worktitle *,
.position,
.position *,
.info,
.info *,
.meta,
.meta *,
.casefooter,
.casefooter *,
.number,
.year,
#side-dialog,
#side-dialog *,
body.work .items .info,
body.work .items .info *,
.case-grid .case-grid-item .info,
.case-grid .case-grid-item .info *,
.admin-translation-lang,
.engine-label,
.engine-modules span,
.store-url {
  font-family: var(--arthage-font-mono) !important;
}

/*
 * ARTHAGE — EDITORIAL WRAP GUARDS
 * The captured text-scramble runtime temporarily uses non-breaking spaces to
 * preserve character positions. For editorial copy blocks, we allow natural
 * wrapping so large statements stay inside the asymmetric grid instead of
 * overflowing the viewport.
 */
.section .col,
.section .html,
.home-content .col,
.home-content .html {
  min-width: 0;
  max-width: 100%;
}

.section .html :where(p, h1, h2, h3, h4, li, dt, dd, span),
.home-content .html :where(p, h1, h2, h3, h4, li, dt, dd, span) {
  white-space: normal !important;
  overflow-wrap: anywhere;
  word-break: normal;
}

.section .html :where(.mega, p.mega, h1.mega, h2.mega),
.home-content .html :where(.mega, p.mega, h1.mega, h2.mega) {
  max-width: 100%;
}

@media (max-width: 768px) {
  body.home .home-content .html p.mega,
  body.home .section .html p.mega.stagger {
    line-height: 1.12 !important;
  }
}

@supports (text-wrap: pretty) {
  .section .html :where(p, li, dt, dd):not(.mega),
  .home-content .html :where(p, li, dt, dd):not(.mega) {
    text-wrap: pretty;
  }
}

/* Homepage first row: keep the two lead project visuals in the same editorial
 * format even when their Sanity source files have different native ratios.
 */
body.home
  .home-content
  .sections
  > section:first-of-type
  > [data-project-slug]:nth-of-type(-n + 2)
  > .image,
body.home
  .home-content
  .sections
  > section:first-of-type
  > [data-project-slug]:nth-of-type(-n + 2)
  > .video {
  aspect-ratio: 4 / 5;
  overflow: hidden;
  width: 100%;
}

body.home
  .home-content
  .sections
  > section:first-of-type
  > [data-project-slug]:nth-of-type(-n + 2)
  > .image
  img,
body.home
  .home-content
  .sections
  > section:first-of-type
  > [data-project-slug]:nth-of-type(-n + 2)
  > .image
  video,
body.home
  .home-content
  .sections
  > section:first-of-type
  > [data-project-slug]:nth-of-type(-n + 2)
  > .video
  img,
body.home
  .home-content
  .sections
  > section:first-of-type
  > [data-project-slug]:nth-of-type(-n + 2)
  > .video
  video {
  height: 100% !important;
  object-fit: cover !important;
  object-position: center;
  width: 100% !important;
}

/*
 * ARTHAGE — APPEARANCE TOKENS
 * The runtime toggles html.light / html.dark from site.appearance.
 * Keep the unqualified html rule aligned with Light mode so the first paint
 * is correct before the runtime adds the explicit .light class.
 */
html,
html.light {
  --black-rgb: var(--dark);
  --white-rgb: 255, 255, 255;
  --black: rgb(var(--dark));
  --white: #ffffff;
  --pure-white: #ffffff;
  --pure-black: #000000;
  --arthage-intro-bg: #ffffff;
  --arthage-intro-fg: rgb(var(--dark));
  color-scheme: light;
  color: rgb(var(--dark));
  background: #ffffff;
}

html.dark {
  --black-rgb: var(--light);
  --white-rgb: 0, 0, 0;
  --black: rgb(var(--light));
  --white: #000000;
  --pure-white: #000000;
  --pure-black: #ffffff;
  --arthage-intro-bg: #000000;
  --arthage-intro-fg: rgb(var(--light));
  color-scheme: dark;
  color: rgb(var(--light));
  background: #000000;
}

body {
  background: inherit;
}

body.home.ascii-intro {
  background: var(--arthage-intro-bg) !important;
}

body.home.ascii-intro .home-content {
  background: var(--arthage-intro-bg) !important;
  color: var(--arthage-intro-fg) !important;
}

body.home.ascii-intro .home-content .image,
body.home.ascii-intro .home-content .video,
body.home.ascii-intro .home-content .ascii {
  background: var(--arthage-intro-bg);
  color: var(--arthage-intro-fg);
}

body.home.ascii-intro .home-content img,
body.home.ascii-intro .home-content video {
  mix-blend-mode: normal !important;
}

/*
 * ARTHAGE — NAVBAR ROUTE PERSISTENCE
 * The captured CSS starts with `html.js #nav { opacity: 0 }` and relies on a
 * route component animation to reveal it. Because the header lives outside
 * `#app`, an SPA navigation from the home intro to `/services` can keep the
 * global navbar in the hidden first-load state. Keep the intro clean, but force
 * the nav visible once home is ready and on every non-home route.
 */
html.js body:not(.home) #nav,
html.js body.home.ready #nav {
  opacity: 1;
}

/*
 * ARTHAGE — PHASE 1 PRE-LAUNCH FREEZE
 * Reversible launch lock. No pages, routes, project assets or href values are
 * deleted: runtime-transforms.mjs only decorates Work/project anchors with
 * classes + aria-disabled/tabindex. Phase 2 rollback lives in arthage.config.mjs.
 */
:root {
  --arthage-freeze-opacity: 0.38;
  --arthage-freeze-muted: rgba(var(--black-rgb), 0.42);
  --arthage-freeze-muted-strong: rgba(var(--black-rgb), 0.58);
}

a.pointer-events-none,
.pointer-events-none {
  pointer-events: none !important;
}

a.cursor-default,
.cursor-default {
  cursor: default !important;
}

.public-launch-hidden,
[data-public-launch-hidden],
.public-launch-hidden[hidden],
[data-public-launch-hidden][hidden] {
  display: none !important;
}

a.prelaunch-disabled-link[data-prelaunch-freeze="work"] {
  color: var(--arthage-freeze-muted) !important;
  opacity: var(--arthage-freeze-opacity) !important;
  cursor: default !important;
  text-decoration: none !important;
}

a.prelaunch-disabled-link[data-prelaunch-freeze="work"].active,
#nav a.prelaunch-disabled-link[data-prelaunch-freeze="work"].active,
.linelist li.active a.prelaunch-disabled-link[data-prelaunch-freeze="work"] {
  animation: none !important;
}

#nav > div:nth-child(2) {
  gap: calc(var(--char) * 3);
}

#nav a.prelaunch-disabled-link[data-prelaunch-freeze="work"] {
  align-items: baseline;
  display: inline-flex;
  white-space: nowrap;
}

@media (max-width: 767px) {
  #nav
    > div:nth-child(2)
    a.prelaunch-disabled-link[data-prelaunch-freeze="work"] {
    display: none !important;
  }

  .mobile-container a.prelaunch-disabled-link[data-prelaunch-freeze="work"] {
    display: block !important;
    color: var(--arthage-freeze-muted) !important;
    opacity: var(--arthage-freeze-opacity) !important;
    pointer-events: none !important;
  }
}

a.prelaunch-project-link[data-prelaunch-freeze="project"] {
  cursor: default !important;
  text-decoration: none !important;
}

body.work
  .items
  .item
  a.prelaunch-project-link[data-prelaunch-freeze="project"],
body.home a.prelaunch-project-link[data-prelaunch-freeze="project"],
.case-grid a.prelaunch-project-link[data-prelaunch-freeze="project"],
.casefooter a.prelaunch-project-link[data-prelaunch-freeze="project"] {
  cursor: default !important;
}

@media (hover: hover) {
  .linelist li:hover a.line:not(.dimmed):not(.inactive),
  .linelist
    li
    a.prelaunch-project-link[data-prelaunch-freeze="project"]:not(.dimmed):hover {
    background: var(--black) !important;
    color: var(--white) !important;
  }

  .linelist li:hover a.line:not(.dimmed):not(.inactive) {
    opacity: 1 !important;
  }

  body.work .items .item:has(a.project-preview:not(.dimmed)):hover,
  body.work .items .case:has(a.project-preview:not(.dimmed):hover).hover .item {
    opacity: 1 !important;
    filter: grayscale(0) !important;
  }

  body.work .items .item:has(a.project-preview:not(.dimmed)):hover .info {
    opacity: 1 !important;
  }

  body.work .items a.project-preview:not(.dimmed) .image img,
  body.work .items a.project-preview:not(.dimmed) .image video {
    transition:
      filter var(--arthage-transition-fast) ease,
      opacity var(--arthage-transition-fast) ease,
      transform var(--arthage-transition-fast) ease;
  }

  body.work .items a.project-preview:not(.dimmed):hover .image img,
  body.work .items a.project-preview:not(.dimmed):hover .image video {
    filter: contrast(1.05);
    transform: scale(1.012);
  }

  body.work .items .item:has(.project-preview.dimmed):hover .info,
  body.work
    .items
    .case:has(.project-preview.dimmed:hover).hover
    .item
    .info {
    opacity: 0 !important;
  }
}

/* ARTHAGE — SANITY CASE STUDY PAGES
 * Transitional project pages reuse the captured Aino case-study grid, but their
 * content now comes from Sanity/fallback copy instead of frozen legacy HTML.
 */
body.case .worktitle {
  align-items: flex-start;
}

body.case .worktitle .solutions {
  max-width: var(--s4);
}

body.case .sections > .section:first-child {
  margin-top: calc(var(--line) * 2);
}

body.case {
  --arthage-case-full-media-ratio: 2 / 1;
  --arthage-case-paired-media-ratio: 1 / 1;
  --arthage-case-media-position: center;
}

body.case .sections .image,
body.case .sections .video {
  background: transparent !important;
  display: block;
  max-height: none !important;
  overflow: hidden;
  width: 100%;
}

body.case .sections .col.w8 > .image,
body.case .sections .col.w8 > .video {
  aspect-ratio: var(--arthage-case-full-media-ratio);
}

body.case .sections .col.w4 > .image,
body.case .sections .col.w4 > .video {
  aspect-ratio: var(--arthage-case-paired-media-ratio);
}

body.case .sections .image img,
body.case .sections .image video,
body.case .sections .video img,
body.case .sections .video video {
  height: 100% !important;
  margin: 0 !important;
  max-height: none !important;
  max-width: none !important;
  object-fit: cover !important;
  object-position: var(--arthage-case-media-position);
  width: 100% !important;
}

/* Merrachi art direction: keep the normalized image formats, but anchor the
 * crop as high as CSS safely allows so portrait heads stay inside the frame.
 * Media #1 is intentionally left slightly lower because it was already framed
 * correctly in the grid.
 */
body.case .sections[data-slug="merrachi"] .image[data-project-slug="merrachi"],
body.case .sections[data-slug="merrachi"] .video[data-project-slug="merrachi"] {
  --arthage-case-media-position: center top;
}

body.case
  .sections[data-slug="merrachi"]
  .image[data-project-slug="merrachi"][data-media-index="1"],
body.case
  .sections[data-slug="merrachi"]
  .video[data-project-slug="merrachi"][data-media-index="1"] {
  --arthage-case-media-position: center 18%;
}

@media (max-width: 768px) {
  body.case {
    --arthage-case-full-media-ratio: 1 / 1;
    --arthage-case-paired-media-ratio: 1 / 1;
  }
}

body.case .sections img[src*="media-placeholder.svg"] {
  mix-blend-mode: normal !important;
  opacity: 1 !important;
}

body.case .sections .monocaps p {
  opacity: 0.62;
}

/* Phase 1 footer polish: quieter, cleaner, fully reversible. */
#footer {
  border-top: 1px solid rgba(var(--black-rgb), 0.1);
  bottom: auto !important;
  margin-top: calc(var(--line) * 4);
  padding: calc(var(--line) * 1.5) var(--char2) calc(var(--line) * 2);
}

#footer .shortcuts {
  align-items: start;
  height: auto !important;
  position: relative;
  top: 0 !important;
  width: 100%;
}

#footer .shortcuts > .col,
#footer .footer-viewport {
  min-width: 0;
}

#footer .shortcuts h2,
#footer .footer-viewport h2,
#footer .location,
#footer .time {
  color: inherit;
}

#footer .shortcuts h2,
#footer .footer-viewport h2 {
  margin-bottom: calc(var(--line) * 0.35);
}

#footer .loctime {
  gap: calc(var(--line) * 0.15);
}

#footer .shortcuts a {
  display: table;
  max-width: 100%;
  position: relative;
  transition:
    color var(--arthage-transition-fast) ease,
    opacity var(--arthage-transition-fast) ease;
}

#footer .shortcuts a:hover {
  color: var(--black);
  opacity: 1;
}

#footer .footer-viewport output {
  display: block;
  font: inherit;
  font-variant-numeric: tabular-nums;
  max-width: 100%;
  white-space: nowrap;
}

html #footer,
html #footer *,
html.light #footer,
html.light #footer * {
  color: #000000 !important;
}

html.dark #footer,
html.dark #footer * {
  color: #ffffff !important;
}

html #footer .footer-muted-link,
html.light #footer .footer-muted-link,
html.dark #footer .footer-muted-link {
  color: var(--arthage-freeze-muted) !important;
  cursor: default !important;
  display: table;
  max-width: 100%;
  opacity: var(--arthage-freeze-opacity) !important;
  pointer-events: none !important;
  text-decoration: none !important;
}

html.dark #footer .footer-muted-link {
  color: rgba(var(--light-rgb), 0.42) !important;
}

@media (min-width: 801px) {
  #footer .shortcuts {
    column-gap: var(--char2);
    display: grid;
    grid-template-columns:
      minmax(0, 1fr) minmax(0, 2fr) minmax(0, 1fr)
      minmax(0, 1fr);
  }

  #footer .shortcuts > .col {
    width: auto !important;
  }
}

@media (max-width: 800px) {
  #footer {
    margin-bottom: 0 !important;
    margin-top: calc(var(--line) * 2);
    padding-bottom: calc(var(--line) * 1.5);
  }

  #footer .shortcuts {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    row-gap: calc(var(--line) * 1.25);
  }

  #footer .shortcuts > .col,
  #footer .footer-viewport {
    max-width: 100% !important;
    width: 100% !important;
  }

  #footer .shortcuts .halfwidth {
    flex: none !important;
  }

  #footer .shortcuts a,
  #footer .footer-viewport output {
    overflow-wrap: anywhere;
    white-space: normal;
    word-break: normal;
  }
}

/* Kill the captured "boss mode" / [!] affordance in every play route. */
.boss-btn,
.boss-overlay,
.boss-close {
  display: none !important;
  pointer-events: none !important;
  visibility: hidden !important;
}

/* Play pages: keep the footer closer and prevent the game viewport from pushing it too far below fold. */
body.play #app {
  min-height: calc(100dvh - var(--line) * 6);
}

body.play #footer {
  margin-top: calc(var(--line) * -2);
  padding-top: calc(var(--line) * 1);
}

@media (max-width: 800px) {
  body.play #app {
    min-height: calc(100dvh - var(--line) * 5);
  }

  body.play #footer {
    margin-top: calc(var(--line) * -1.25);
  }
}

/* Progressive enhancement: keep /work readable if the runtime fails, without
 * fighting the native Grid/List switch once it writes inline display styles.
 */
html.js body.work .gridcontainer:not([style*="display"]) {
  display: block;
}

html.js body.work .listcontainer:not([style*="display"]) {
  display: none;
}

body.work .work-project-list {
  padding-top: calc(var(--line) * 3);
}

/*
 * Example — uncomment and adapt:
 *
 * nav a {
 *   transition: opacity var(--arthage-transition-fast) ease;
 * }
 *
 * nav a:hover {
 *   opacity: .55;
 * }
 */

/* ── Fix rendu ASCII / PIXEL sur les médias "cover" ─────────────────────────
   Le renderer texte/pixel ne sait dimensionner un élément `object-fit: cover`
   qu'à partir de son srcset (les <video> en sont même exclues). Un média grille
   cover sans srcset exploitable donne width/height 0 -> drawImage throw -> toute
   la boucle de conversion (et le menu des modes) se fige.
   En mode ascii/pixel le média est de toute façon masqué : on retire `cover`
   pour que le renderer prenne son chemin de dessin plein-cadre, sûr. */
html.textmode .image img,
html.textmode .image video,
html.pixelmode .image img,
html.pixelmode .image video {
  object-fit: fill !important;
}

/* Home intro reveal vs text/pixel mode.
   The first-load intro is an image-mode animation: it reveals the above-fold
   home media and fades their `.ascii` layer to opacity 0 via an inline style.
   In text/pixel mode the real media is hidden, so that inline fade left the
   home cards black. Keep the ASCII layer visible in those modes (it now has
   content thanks to the cover cross-origin fix). Beats the inline opacity. */
html.textmode .home-content .ascii,
html.pixelmode .home-content .ascii {
  opacity: 1 !important;
}

/*
 * ARTHAGE — CHROME INTER OVERRIDE
 * Rollback: comment this block if the chrome should return to JetBrains Mono.
 * The rest of the site keeps the Inter + JetBrains Mono split defined above;
 * play/game surfaces remain monospace-safe.
 */
#nav,
#nav *,
.mobile-container,
.mobile-container *,
#footer,
#footer *,
#side-dialog .dialog-header,
#side-dialog .dialog-header *,
#side-dialog > .dialog-header button,
#side-dialog > .dialog-header button * {
  font-family: var(--arthage-font-body) !important;
}

/*
 * ARTHAGE — HOME ASCII HEADER
 * Route: /
 * The external ASCII iframe is used only as the top homepage header. Do not
 * lock body.home to black: the rest of the index must keep following the
 * active Light/Dark appearance tokens.
 */
body.home.home-ascii-active #nav,
body.home.home-ascii-active #nav * {
  color: rgb(var(--dark)) !important;
}

body.home .home-ascii-hero {
  --black-rgb: var(--dark);
  --white-rgb: 255, 255, 255;
  background: #ffffff;
  color: rgb(var(--dark));
  height: 100dvh;
  margin: calc(var(--line) * -3) calc(var(--char) * -2) calc(var(--line) * 5);
  overflow: hidden;
  position: relative;
}

body.home .home-ascii-hero__frame {
  background: #ffffff;
  border: 0;
  filter: none;
  height: 100%;
  inset: 0;
  opacity: 1;
  pointer-events: none;
  position: absolute;
  transform: none;
  transform-origin: center;
  width: 100%;
  z-index: 0;
}

body.home .home-ascii-hero::after {
  background: linear-gradient(
    to bottom,
    rgba(255, 255, 255, 0) 0%,
    rgba(255, 255, 255, 0.92) 72%,
    #ffffff 100%
  );
  bottom: 0;
  content: "";
  height: min(34svh, 340px);
  left: 0;
  pointer-events: none;
  position: absolute;
  right: 0;
  z-index: 1;
}

body.home .home-ascii-hero__copy {
  bottom: clamp(24px, 4svh, 40px);
  color: rgb(var(--dark));
  display: grid;
  font-family: var(--arthage-font-body);
  gap: 0;
  left: clamp(16px, 3vw, 32px);
  max-width: min(920px, calc(100vw - 32px));
  pointer-events: none;
  position: absolute;
  width: min(920px, calc(100vw - 32px));
  z-index: 3;
}

body.home .home-ascii-hero__copy p {
  margin: 0;
}

body.home .home-ascii-hero__slogan {
  font-family: var(--arthage-font-body) !important;
  font-feature-settings: "ss05";
  font-size: clamp(44px, calc(var(--font-size) * 3.55), 64px);
  font-variation-settings: "MONO" 0, "wght" 700;
  font-weight: 720;
  letter-spacing: -0.03em;
  line-height: 0.96;
  max-width: min(920px, calc(100vw - 32px));
  text-wrap: normal;
  white-space: normal;
}

body.home .home-ascii-hero__slogan br {
  display: block;
}

body.home .home-ascii-hero__slogan [data-home-ascii-line] {
  display: block;
  min-height: 1em;
  white-space: nowrap;
}

body.home .home-ascii-hero__time {
  font-family: var(--arthage-font-mono) !important;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: -0.025em;
  line-height: 1;
  margin-top: 6px !important;
  text-transform: uppercase;
}

body.home .home-ascii-hero__description {
  font-size: clamp(14px, calc(var(--font-size) * 1.08), 17px);
  font-weight: 400;
  letter-spacing: -0.018em;
  line-height: 1.18;
  margin-top: 16px !important;
  max-width: 520px;
}

html.dark body.home.home-ascii-active #nav,
html.dark body.home.home-ascii-active #nav * {
  color: #f5f5f0 !important;
}

html.dark body.home .home-ascii-hero {
  --black-rgb: 245, 245, 240;
  --white-rgb: 0, 0, 0;
  background: #000000;
  color: #f5f5f0;
}

html.dark body.home .home-ascii-hero__frame {
  background: #000000;
  filter: invert(1);
  opacity: 1;
}

html.dark body.home .home-ascii-hero::after {
  background: linear-gradient(
    to bottom,
    rgba(0, 0, 0, 0) 0%,
    rgba(0, 0, 0, 0.92) 72%,
    #000000 100%
  );
  content: "";
}

html.dark body.home .home-ascii-hero__copy {
  color: #f5f5f0;
}

body.home .home-content {
  background: var(--white);
  color: var(--black);
  position: relative;
  z-index: 1;
}

@media (max-width: 768px) {
  body.home .home-ascii-hero {
    height: 100svh;
    min-height: 100svh;
    margin-bottom: calc(var(--line) * 3);
  }

  body.home .home-ascii-hero__frame {
    height: calc(100% + 2px);
    inset: -2px 0 auto;
    transform: none;
    transform-origin: center top;
  }

  body.home .home-ascii-hero__copy {
    bottom: clamp(28px, 5svh, 48px);
    left: 16px;
    max-width: calc(100vw - 32px);
    width: calc(100vw - 32px);
  }

  body.home .home-ascii-hero__slogan {
    font-size: clamp(26px, 7.2vw, 34px);
    letter-spacing: -0.03em;
    line-height: 1.02;
    max-width: calc(100vw - 32px);
    text-wrap: normal;
    white-space: nowrap;
  }

  body.home .home-ascii-hero__time {
    font-size: 10px;
    letter-spacing: -0.02em;
    margin-top: 10px !important;
  }

  body.home .home-ascii-hero__description {
    font-size: clamp(12px, 3.25vw, 13px);
    letter-spacing: -0.01em;
    line-height: 1.28;
    margin-top: 14px !important;
    max-width: 38ch;
  }
}

@media (max-width: 430px) {
  body.home .home-ascii-hero {
    height: 100svh;
    min-height: 100svh;
  }

  body.home .home-ascii-hero__frame {
    transform: none;
  }

  body.home .home-ascii-hero__slogan {
    font-size: clamp(24px, 6.8vw, 29px);
    max-width: calc(100vw - 32px);
    white-space: nowrap;
  }

  body.home .home-ascii-hero__description {
    max-width: 34ch;
  }
}
