/* ============================================================
   MODULE "shell" - page chrome: hero, workstation index cards, AI note,
   tools marquee, contact, footer and its back-to-top link, 404.
   It also carries the page rhythm: every section holds one screen and
   composes inside it, so no joint between two blocks leaves the reader
   on empty paper (sections 3b, 4 and 6). The hero is deliberately left
   out: it is being rebuilt in its own module.
   Loaded AFTER styles.css, so every rule here may override it.
   Only rules that are NEW or that fix a bug live in this file.
   ============================================================ */

/* ------------------------------------------------------------
   1. Typewriter chips (.poste-typed) - clipping fix
   ------------------------------------------------------------
   styles.css pins .tw-live with `inset: 0`, so the live text box is
   exactly the pill's padding box. Combined with the px `min-width`
   that app.js used to freeze on the element, any later layout change
   (phone rotation, browser zoom, the 640 px breakpoint that shrinks
   font-size and padding, the mono webfont swapping in) left the pill
   at a stale width and the text got cut off.
   app.js no longer freezes a width: the ghost span (same text, same
   style, in flow) reserves it. Here we make the live overlay size to
   its own content instead of to the parent box, so the animated text
   can never be clipped by the pill, whatever the pill's width.
   Scoped to .poste-typed on purpose: .term-type belongs to the
   terminal module and keeps the styles.css behaviour. */

.poste-typed .tw-live {
  inset: 0 auto auto 0;
  width: max-content;
  max-width: none;
}

/* ------------------------------------------------------------
   2. No page chrome: --topbar-h is 0
   ------------------------------------------------------------
   The sticky bar (brand, six nav links, status pill, burger menu) has been
   removed from every page. Its height used to be measured by js/shell.js
   and published as --topbar-h, and other rules still read that variable to
   clear the bar: the scroll padding below and the panel geometry of
   css/stations.css, which offsets the section box so that a link lands on
   the pinned panel at progress 0. Rather than hunting every usage, the
   variable stays and is simply worth zero, which makes all of them
   collapse to "flush with the top of the page".
   It is declared in CSS and not in JS so a page without JS gets the same
   geometry, instead of falling back on the old 88 px. */

:root { --topbar-h: 0px; }

html { scroll-padding-top: var(--topbar-h, 0px); }

/* ------------------------------------------------------------
   3. Hero
   ------------------------------------------------------------ */

/* The English headline is much longer than the French one it replaces
   ("Software developer and engineering student." against "Du code, des
   pixels, du métal."). At the original clamp it ran to four lines in the
   two-column layout and the forced break stopped meaning anything.
   Only the two-column range is retouched; the one-column sizes from
   styles.css still apply below 901 px. */
@media (min-width: 901px) {
  .hero h1 { font-size: clamp(2.5rem, 4.6vw, 3.3rem); }
}

/* "25 h", "850+", "8 months": the figures now carry a unit, so the
   column needs a little more room and the value must not wrap oddly. */
.hero-stats { grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); }

.hero-stats dt {
  font-size: clamp(1.55rem, 2.4vw, 1.9rem);
  text-wrap: balance;
}

.hero-stats dd { max-width: 15em; }

/* ------------------------------------------------------------
   3b. Workstation index (#work): compose the screen
   ------------------------------------------------------------
   .section now guarantees one screen. Left alone, #work would spend that
   screen on 654 px of content and 250 px of slack piled under the cards,
   right before the pinned Computer scene, which opens almost empty by
   design: two half-empty screens in a row. So the card row takes the free
   height and the three drawings grow into it. Spacing and sizing only, no
   change to the cards themselves (styles.css "SOMMAIRE les postes"). */

.postes-index {
  display: flex;
  flex-direction: column;
  /* What the cards do not take (very tall screens) is split above and
     below them instead of being dumped under the row. */
  justify-content: center;
}

@media (min-width: 901px) {
  .postes-index .poste-cards {
    flex: 1 1 auto;
    min-height: 0;
    /* The card is a sheet, not a column: past this the drawing can no
       longer grow with it (it is capped by the card's width) and the
       inside of the card starts to look empty. */
    max-height: 36rem;
  }

  .postes-index .poste-card-svg { flex: 1 1 auto; min-height: 0; }

  .postes-index .poste-card-svg svg { max-height: 100%; }
}

/* ------------------------------------------------------------
   4. AI note and tools marquee: one deliberate divider
   ------------------------------------------------------------
   The two used to read as leftovers: a 191 px note floating on plain paper
   between the Workbench and Contact, then a 50 px strip of its own. They
   are now a single full-bleed band, a note storey on paper-2 sitting
   straight on the marquee storey, with one hairline above and one below,
   which is the language the site already uses for .section-panel. */

.ai-band {
  max-width: none;
  margin: 0;
  padding: clamp(1.75rem, 4vh, 2.75rem) clamp(1.25rem, 4vw, 3rem);
  background: var(--paper-2);
  border-top: 1px solid var(--line);
}

.ai-band .ai-note {
  max-width: var(--maxw);
  margin: 0 auto;
}

/* ------------------------------------------------------------
   5. Tools marquee
   ------------------------------------------------------------ */

/* The pause button reserves a 44 px hit area through its ::after, but the
   band itself was only ~43 px tall and clips it (`.marquee { overflow:
   hidden }`). A hair more vertical padding lets the whole target fit. */
.marquee { padding: 0.85rem 0; }

/* The note band above already draws that line, and two hairlines 1 px
   apart read as a rendering artefact. The divider keeps a single rule at
   its top and a single rule at its bottom. */
.ai-band + .marquee { border-top: 0; }

/* ------------------------------------------------------------
   6. Contact: one composed screen
   ------------------------------------------------------------
   styles.css used to cap the section at 100svh - 88px and stack
   everything against the top: 0.89 screen with ~340 px of dead paper
   under the last line. It now takes a full screen from .section, centres
   the call to action in it, and closes on a bottom rule. */

.section-contact {
  display: flex;
  flex-direction: column;
}

/* Three bands, like the foot of a drawing sheet: the statement lands right
   under the bar (so the #contact anchor lands on text, not on paper), the
   call to action sits on its own rule low on the screen, and the location
   closes on the bottom rule. The free height goes between the bands and is
   held by those rules, so it reads as structure and not as a dead end. */
.contact-main {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  /* Le bloc etait CENTRE puis pousse vers le haut par un gros padding bas :
     toute la hauteur libre de l'ecran tombait d'un seul cote et laissait
     329 px de papier vide entre les boutons et la ligne "Based in Lille",
     ce qui se lisait comme un oubli. La meme hauteur libre est maintenant
     repartie entre les trois bandes (au-dessus du titre, entre le titre et
     les boutons, sous les boutons) : c'est la respiration d'une feuille,
     plus un trou. */
  justify-content: space-evenly;
  gap: clamp(1.75rem, 4.5vh, 3rem);
  /* Centre optique, pas geometrique : il en reste juste de quoi poser le
     bloc au-dessus du milieu. */
  padding-bottom: clamp(0.5rem, 2.5vh, 2rem);
}

.section-contact .section-head { margin-bottom: 0; }

/* A closing screen carries its sentence bigger than a mid-page heading. */
.section-contact .section-head h2 { font-size: clamp(2rem, 4vw, 3.3rem); }

.section-contact .contact-actions {
  margin-bottom: 0;
  padding-top: clamp(1.1rem, 2.5vh, 1.8rem);
  border-top: 1px dashed var(--line);
}

.contact-meta {
  margin-top: clamp(1.5rem, 4vh, 2.5rem);
  padding-top: clamp(0.9rem, 2vh, 1.4rem);
  border-top: 1px dashed var(--line);
}

/* ------------------------------------------------------------
   7. Footer
   ------------------------------------------------------------ */

.footer p + p { margin-top: 0.45rem; }

/* The single way back to the top of the page, and the only one on the whole
   site: a mono label at the very end, in the language of the drawing sheet
   labels. Nothing sticky, nothing floating. The rule above it closes the
   page the way the dashed rules close #contact. */
.footer-top {
  margin-bottom: 0.9rem;
  padding-bottom: 0.85rem;
  border-bottom: 1px dashed var(--line);
}

.back-to-top {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  min-height: 44px;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-soft);
  text-decoration: none;
  transition: color 0.2s;
}

/* The upward tick of a dimension arrow, drawn in text so it needs no SVG. */
.back-to-top::before {
  content: "\2191";
  font-size: 0.85rem;
  line-height: 1;
}

.back-to-top:hover { color: var(--ink); }

/* Same label on 404.html, but it leads back to the site and not to the top
   of the page: the tick points left. */
.back-to-top.back-home::before { content: "\2190"; }

/* Discreet through size, not through opacity: a faded 11 px mono line would
   drop under the 4.5:1 contrast floor. */
.footer-legal { font-size: 0.7rem; }

/* ------------------------------------------------------------
   8. 404 page (uses styles.css + this file, no page of its own)
   ------------------------------------------------------------ */

.nf-main {
  display: grid;
  place-items: center;
  padding: clamp(3rem, 12vh, 7rem) clamp(1.25rem, 4vw, 3rem);
  /* One screen minus the footer; there is no bar to subtract any more. */
  min-height: calc(100svh - 5.5rem);
  position: relative;
  background:
    linear-gradient(to bottom, transparent, var(--paper) 92%),
    repeating-linear-gradient(0deg, color-mix(in srgb, var(--blue-deep) 7%, transparent) 0 1px, transparent 1px 56px),
    repeating-linear-gradient(90deg, color-mix(in srgb, var(--blue-deep) 7%, transparent) 0 1px, transparent 1px 56px),
    var(--paper);
}

.nf-card {
  width: 100%;
  max-width: 560px;
  background: var(--card);
  border: 1px solid var(--line);
  border-left: 3px solid var(--brass);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: clamp(1.75rem, 5vw, 2.75rem);
}

.nf-card h1 {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: clamp(2rem, 6vw, 3rem);
  line-height: 1.05;
  letter-spacing: -0.025em;
  margin-bottom: 0.9rem;
}

.nf-card .lede { margin-bottom: 1.75rem; }

.nf-cartouche {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  margin-top: 2rem;
  border: 1px solid var(--line);
  border-radius: 10px;
  overflow: hidden;
}

.nf-cartouche span {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  padding: 0.55rem 0.8rem;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  color: var(--ink);
}

.nf-cartouche span + span { border-left: 1px solid var(--line); }

.nf-cartouche b {
  font-weight: 400;
  font-size: 0.6rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--ink-soft);
}

@media (max-width: 420px) {
  .nf-cartouche { grid-template-columns: 1fr 1fr; }
  .nf-cartouche span:nth-child(3) { border-left: 0; border-top: 1px solid var(--line); grid-column: 1 / -1; }
}

/* Hero facts: two plain lines instead of animated counters. Mono label,
   text in the body face, under the same hairline the counters used. */
.hero-facts {
  display: flex;
  flex-wrap: wrap;
  gap: 0.9rem 3rem;
  margin: 0;
  border-top: 1px solid var(--line);
  padding-top: 1.4rem;
}
.hero-facts div { display: grid; gap: 0.3rem; }
.hero-facts dt {
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-size: 0.72rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.hero-facts dd { margin: 0; font-size: 1.02rem; color: var(--ink); }
