@charset "utf-8";
/* ==========================================================================
   CHAPA — Grafite e Zinco
   JVperfis design system · tokens, reset, base type, utilities
   v1.0 — spec: DESIGN-SYSTEM.md (that file decides; this one implements)
   --------------------------------------------------------------------------
   FONTS ARE NOT @import-ed HERE ON PURPOSE. @import serialises the request
   behind this stylesheet. Put this in <head> BEFORE this file:

   <link rel="preconnect" href="https://fonts.googleapis.com">
   <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
   <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Archivo:wdth,wght@62..125,400..900&family=IBM+Plex+Mono:wght@400;500;600&family=IBM+Plex+Sans:wght@400;500;600&display=swap">

   Google Fonts is the ONLY permitted external origin. No icon fonts, no CDN
   scripts, no external images. Every icon is inline SVG.
   ========================================================================== */

/* ==========================================================================
   1. TOKENS
   Declared once, as literal hex. No prefers-color-scheme branching and no
   dark-mode toggle: the page's tonality IS the design, so both grounds are
   painted explicitly and identically for every viewer.
   ========================================================================== */

:root {

  /* --- 1.1 Structure · dark side (~78% of page height) ------------------- */
  --grafite:        #141517;   /* page ground: header, Empresa, Novidades, footer */
  --grafite-fundo:  #0E0F11;   /* deepest step: hero ground, hero spec strip     */
  --painel:         #1B1D20;   /* raised panel: Missao/Visao, form half          */
  --aco:            #5A5D60;   /* mid steel: field underlines, checkbox border   */
  --linha:          rgba(216, 219, 222, 0.16);  /* 1px hairlines on dark         */
  --linha-forte:    rgba(216, 219, 222, 0.34);  /* 1px block borders on dark     */

  /* --- 1.2 Ink · dark side ----------------------------------------------- */
  --zinco:          #D8DBDE;   /* body text on dark            13.14:1 on grafite */
  --zinco-vivo:     #F2F4F6;   /* headlines, figures           16.57:1            */
  --zinco-mudo:     #8A8D90;   /* labels, captions, kickers     5.48:1            */
  /* NOTE: --zinco-mudo is BANNED over photography (4.25:1 worst case). See §5.5 */

  /* --- 1.3 The zinc catalogue slab ---------------------------------------- */
  --chapa:          #E6E8EA;   /* catalogue ground                               */
  --chapa-clara:    #F2F4F6;   /* sticky filter bar; PALETE cell tonal lift      */
  --chapa-sombra:   #DCDFE2;   /* SKU row hover                                  */
  --tinta:          #101113;   /* catalogue ink                15.38:1 on chapa   */
  --tinta-mudo:     #4A4D50;   /* reference codes               6.93:1           */
  --tinta-rotulo:   #5A5D60;   /* labels AND the em-dash        5.39:1           */
  --linha-tinta:    #1A1B1D;   /* 1px hairlines, 2px family + section rules      */

  /* --- 1.4 THE ACCENT · one colour, two stops ----------------------------- */
  /* Measured from the worklight in factory-04.jpg: dominant warm hue 38deg.   */
  --ambar:          #EFA72A;   /* DARK SIDE ONLY  8.90:1 on grafite / 9.20:1 for --tinta on it */
  --ambar-premir:   #D8940F;   /* pressed state of an amber fill                 */
  --ambar-tinta:    #A66A04;   /* ZINC SLAB ONLY  3.65:1 on chapa — clears 1.4.11 */
  /* These are ONE accent at two lightnesses, never two colours.
     There is deliberately no .amber utility class and no --accent alias:
     amber appears in the 8 registered places only (DESIGN-SYSTEM.md §5.1). */

  /* --- 1.5 Secondary · structural only, never a button --------------------- */
  --azul:           #1B6291;   /* the logo's blue. Brand reference, decorative only */
  --azul-linha:     #2670A3;   /* usable stop: 4px edges, footer rule   3.42:1    */
  --azul-luz:       #3A8FC9;   /* inline links ON DARK ONLY             5.18:1    */

  /* --- 1.6 The catalogue plate -------------------------------------------- */
  /* The corner of the studio ground the 26 pieces are composited onto. It exists
     so the plate behind an image that has not loaded is the image's own colour
     rather than a white flash. Match it to GROUND_FAR in tools/cutout/compose_dark.py.
     The photograph is NOT flat at this value — it lifts to roughly #384450 behind
     the piece and falls back to this at the corners. That pool of light is what
     makes a dark ground work at all: the darkest steel faces measure luminance
     0.012, so against a FLAT dark field they disappear. Against the lighter middle
     of the pool they read as dark shapes on a lighter ground, which is all a
     silhouette needs. Two earlier grounds failed this test and are withdrawn —
     --bancada #3E3226 (0.034) and --madeira #9C7444, with .regra-madeira, their
     only other user. Equal luminance is what kills a silhouette, not darkness. */
  --placa:          #181E26;

  /* --- 1.7 Type families --------------------------------------------------- */
  --ff-display: 'Archivo', 'Archivo Black', 'Arial Narrow', sans-serif;
  --ff-mono:    'IBM Plex Mono', ui-monospace, 'SFMono-Regular', Menlo, monospace;
  --ff-prosa:   'IBM Plex Sans', 'Helvetica Neue', sans-serif;
  /* No system-ui anywhere. Archivo never below 1.125rem; Plex Mono never above
     1.375rem; Plex Sans never in a data cell. */

  /* --- 1.8 Type scale ------------------------------------------------------ */
  /* MEASURED, do not raise. "PERFILAGEM" at Archivo 900 wdth 120 with
     ls -0.032em costs 8.02em of advance. At 375px the line box is 335px, so
     the type may not exceed 41px; at 320px it may not exceed 35px. Hence
     10vw (37.5px at 375, 32px at 320) and a 2rem floor. A 13vw/3.25rem hero
     truncates the company's own first word to "PERFILAGE". */
  /* The 10vw is the measured width constraint (see the note above). The 16vh is
     the HEIGHT constraint, and it is new: the hero is one screen tall with its
     content anchored to the bottom, so on a wide-but-short window — a laptop at
     1408x829, say — three lines at 10vw simply do not fit between the header
     and the fold, and the call to action is pushed off the screen. min() takes
     whichever constraint bites first. At 375x812 and 320x640, 10vw still wins
     by a wide margin, so nothing about the phone layout changes. */
  --fs-hero:        clamp(2rem, min(10vw, 16vh), 10rem);
  --fs-seccao:      clamp(2.25rem, 6.5vw, 4.5rem);
  --fs-familia:     clamp(1.5rem, 4.6vw, 2rem);
  --fs-lead:        clamp(1.0625rem, 2.4vw, 1.3125rem);
  --fs-sku:         1.125rem;      /* SKU name, mobile (Archivo)   */
  --fs-sku-mesa:    1.0625rem;     /* SKU name, desktop (Plex Sans) */
  --fs-palete:      1.375rem;      /* THE number, mobile            */
  --fs-figura:      1.1875rem;     /* other figures, mobile         */
  --fs-figura-mesa: 1.0625rem;     /* figures, desktop              */
  --fs-ref:         0.9375rem;     /* reference code                */
  --fs-corpo:       1.0625rem;
  --fs-rotulo:      0.75rem;       /* LABEL FLOOR — nothing smaller */
  --fs-unidade:     0.6875rem;     /* unit suffix — the ONLY exception */
  --fs-kicker:      0.75rem;

  /* --- 1.9 Line-heights + tracking ---------------------------------------- */
  --lh-hero: 0.84;  --ls-hero: -0.032em;
  --lh-sec:  0.92;  --ls-sec:  -0.022em;
  --lh-fam:  0.95;  --ls-fam:  -0.015em;
  --lh-corpo: 1.62;
  --lh-lead:  1.44;
  --ls-rotulo: 0.12em;
  --ls-kicker: 0.18em;
  --ls-ref:    0.04em;
  --ls-unidade: 0.1em;

  /* --- 1.10 Space scale (8px base) ----------------------------------------- */
  --s-1: 4px;   --s-2: 8px;   --s-3: 12px;  --s-4: 16px;
  --s-5: 24px;  --s-6: 32px;  --s-7: 48px;  --s-8: 64px;
  --s-9: 96px;  --s-10: 128px; --s-11: 192px;

  /* --- 1.11 Grid ----------------------------------------------------------- */
  --medida:    1440px;  /* content max-width */
  --margem:    20px;    /* page margin — 40px at >=900px */
  --goteira:   24px;    /* gutter */
  --pad-seccao: var(--s-9);            /* 96px mobile, 160px desktop */

  /* --- 1.12 Chrome offsets (never a magic number) --------------------------- */
  --h-header:  64px;
  --h-filtro:  64px;                   /* 56px at >=900px */
  --scroll-offset: calc(var(--h-header) + var(--h-filtro) + var(--s-4));

  /* --- 1.13 Motion ---------------------------------------------------------- */
  --ease:      cubic-bezier(.16, .84, .3, 1);   /* reveals */
  --ease-mec:  linear;                          /* hover — machinery, not silk */
  --t-hover:   90ms;
  --t-ui:      180ms;
  --t-reveal:  520ms;

}

@media (min-width: 900px) {
  :root {
    --margem: 40px;
    --pad-seccao: 160px;
    --h-filtro: 56px;
  }
}

/* ==========================================================================
   2. RESET
   ========================================================================== */

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

/* The one !important in the codebase, and it is deliberate: it stops any
   future component from softening. This is sheet metal, not a SaaS. */
*, *::before, *::after { border-radius: 0 !important; }

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* user-scalable=no is BANNED in the viewport meta. The old site's pinch-lock
     is one of the things being fixed. */
}

body,
h1, h2, h3, h4, h5, h6,
p, figure, blockquote, dl, dd, ul, ol, fieldset, legend {
  margin: 0;
  padding: 0;
}

ul[role="list"], ol[role="list"] { list-style: none; }

body {
  min-height: 100svh;
  /* Explicit background so the host never shows through. */
  background: var(--grafite);
  color: var(--zinco);
  font-family: var(--ff-prosa);
  font-size: var(--fs-corpo);
  font-weight: 400;
  line-height: var(--lh-corpo);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  overflow-x: clip;   /* the page NEVER scrolls sideways */

  /* Roughly four fifths of this page is graphite, and the OS paints a bright
     bar down the right of it. These are the sheet's own greys, in the scrollbar.
     `auto` rather than `thin`: macOS ignores scrollbar-color entirely unless a
     width is named, and a thin bar is a smaller target for a gloved hand.
     The track is left to the platform — on macOS it is transparent whatever is
     asked for, so the thumb is the only thing that may carry the contrast. */
  scrollbar-color: var(--aco) var(--grafite-fundo);
  scrollbar-width: auto;
}

/* Someone who has asked the system for more contrast is not asking for the
   house greys. Never transitioned — animating scrollbar-color flickers. */
@media (prefers-contrast: more) {
  body { scrollbar-color: var(--zinco-vivo) var(--grafite-fundo); }
}

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

input, button, textarea, select {
  font: inherit;
  color: inherit;
  background: none;
  border: none;
}
button { cursor: pointer; }

table { border-collapse: collapse; border-spacing: 0; width: 100%; }
th { text-align: left; font-weight: inherit; }

a { color: inherit; text-decoration: none; }

/* box-shadow is used ZERO times in this document. */
* { box-shadow: none; }

hr { border: 0; border-top: 1px solid var(--linha); margin: 0; }

/* ==========================================================================
   3. BASE TYPOGRAPHY
   ========================================================================== */

/* --- 3.1 Display ---------------------------------------------------------- */
/* Archivo never appears below 1.125rem. padding-block: 0.08em is MANDATORY —
   at line-height 0.84 it is the only thing protecting C-cedilla and A-tilde
   from clipping. NEVER put overflow:hidden on an element holding a headline. */

/* Archivo arrives from a third origin with font-display: swap, so for the first
   moments the page is set in Arial Narrow / Helvetica. Those have a different
   cap height, and at --fs-hero a swap moves the whole first screen.
   font-size-adjust: cap-height from-font reads Archivo's own ratio and scales
   whatever is standing in so the capitals occupy the same height — measured on
   the caps because every one of these three styles is uppercase.
   Where the property is unsupported the swap is simply as abrupt as before. */
.t-hero, .t-seccao, .t-familia {
  font-family: var(--ff-display);
  text-transform: uppercase;
  padding-block: 0.08em;
  overflow: visible;
  font-size-adjust: cap-height from-font;
  /* Headlines here are two to four words over two or three lines: exactly the
     case balance is for, and short enough to stay under the 6-line algorithm
     limit that would silently turn it off. */
  text-wrap: balance;
}

.t-hero {
  font-size: var(--fs-hero);
  font-weight: 900;
  font-stretch: 120%;
  font-variation-settings: 'wdth' 120, 'wght' 900;
  line-height: var(--lh-hero);
  letter-spacing: var(--ls-hero);
  color: var(--zinco-vivo);
}

.t-seccao {
  font-size: var(--fs-seccao);
  font-weight: 800;
  font-stretch: 115%;
  font-variation-settings: 'wdth' 115, 'wght' 800;
  line-height: var(--lh-sec);
  letter-spacing: var(--ls-sec);
  color: var(--zinco-vivo);
}

.t-familia {
  font-size: var(--fs-familia);
  font-weight: 800;
  font-stretch: 118%;
  font-variation-settings: 'wdth' 118, 'wght' 800;
  line-height: var(--lh-fam);
  letter-spacing: var(--ls-fam);
}

/* --- 3.2 Mono — every machine-produced value ------------------------------ */
/* Plex Mono never exceeds 1.375rem, and only reaches it in the mobile PALETE
   figure and the amber phone CTA. */

.t-kicker {
  font-family: var(--ff-mono);
  font-size: var(--fs-kicker);
  font-weight: 500;
  line-height: 1.2;
  letter-spacing: var(--ls-kicker);
  text-transform: uppercase;
  color: var(--zinco-mudo);
}

.t-rotulo {                       /* data + column labels — THE FLOOR */
  font-family: var(--ff-mono);
  font-size: var(--fs-rotulo);
  font-weight: 500;
  line-height: 1.25;
  letter-spacing: var(--ls-rotulo);
  text-transform: uppercase;
  color: var(--tinta-rotulo);
}

.t-unidade {                      /* the only type permitted below 0.75rem,
                                     and only directly beneath a .t-rotulo */
  font-family: var(--ff-mono);
  font-size: var(--fs-unidade);
  font-weight: 400;
  line-height: 1.2;
  letter-spacing: var(--ls-unidade);
  text-transform: lowercase;
  color: var(--tinta-rotulo);
}

.t-ref {
  font-family: var(--ff-mono);
  font-size: var(--fs-ref);
  font-weight: 500;
  line-height: 1.3;
  letter-spacing: var(--ls-ref);
  color: var(--tinta-mudo);
  font-size-adjust: ch-width from-font;
}

/* Figures sit in a five-column grid. Plex Mono and the system monospace do not
   share an advance width, so a swap re-rags every pallet number in the table.
   ch-width is the metric that matters for a monospaced face. */
.t-figura {
  font-family: var(--ff-mono);
  font-weight: 600;
  font-size: var(--fs-figura);
  line-height: 1.15;
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
  color: var(--tinta);
  font-size-adjust: ch-width from-font;
}
.t-figura--palete { font-size: var(--fs-palete); line-height: 1.1; }

@media (min-width: 900px) {
  .t-figura, .t-figura--palete {
    font-size: var(--fs-figura-mesa);
    line-height: 1.3;
    letter-spacing: 0.01em;
  }
}

.t-legenda {
  font-family: var(--ff-mono);
  font-size: var(--fs-rotulo);
  font-weight: 400;
  line-height: 1.3;
  letter-spacing: 0.1em;
  color: var(--zinco-mudo);
}

/* --- 3.3 Prose — Plex Sans NEVER appears in a data cell -------------------- */

/* Plex Sans standing in as Helvetica Neue for a few hundred milliseconds moves
   every line below it. x-height is the right metric for lowercase prose.
   `pretty` costs more than the greedy algorithm, so it goes on the two prose
   classes and nowhere else — never on a data cell, never globally. */
.t-lead {
  font-family: var(--ff-prosa);
  font-size: var(--fs-lead);
  font-weight: 400;
  line-height: var(--lh-lead);
  max-width: 46ch;
  color: var(--zinco);
  font-size-adjust: from-font;
  text-wrap: pretty;
}

.t-corpo {
  font-family: var(--ff-prosa);
  font-size: var(--fs-corpo);
  font-weight: 400;
  line-height: var(--lh-corpo);
  max-width: 62ch;
  color: var(--zinco);
  font-size-adjust: from-font;
  text-wrap: pretty;
}
.t-corpo + .t-corpo { margin-top: var(--s-4); }

/* --- 3.4 Links ------------------------------------------------------------ */

.lig {                            /* inline link on dark */
  color: var(--azul-luz);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.22em;
  transition: text-decoration-thickness var(--t-ui) var(--ease-mec);
}
.lig:hover { text-decoration-thickness: 2px; }

.slab-zinco .lig {                /* inline link on zinc — never blue, never amber */
  color: var(--tinta);
}

/* ==========================================================================
   4. FOCUS · loud, never removed
   Gloved hands and keyboard users both need it.
   ========================================================================== */

:focus { outline: none; }         /* replaced, not removed */

:focus-visible {
  outline: 2px solid var(--ambar);
  outline-offset: 2px;
}

.slab-zinco :focus-visible {
  outline: 2px solid var(--tinta);
  outline-offset: 2px;
  /* 2px amber inner ring, drawn without box-shadow: */
  border-color: var(--ambar-tinta);
}

/* ==========================================================================
   5. SELECTION
   ========================================================================== */

::selection      { background: var(--ambar);       color: var(--tinta); }
.slab-zinco ::selection { background: var(--ambar-tinta); color: var(--chapa-clara); }

/* ==========================================================================
   6. SHARED UTILITIES
   ========================================================================== */

/* --- 6.1 Measure + bleed --------------------------------------------------- */

.u-medida {                       /* type and data respect 1440px */
  width: 100%;
  max-width: var(--medida);
  margin-inline: auto;
  padding-inline: var(--margem);
}

.u-bleed {                        /* slabs run to the viewport edge */
  width: 100%;
  margin-inline: 0;
}

.u-grelha {                       /* the 12-column drawing grid */
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--goteira);
}

/* --- 6.2 Slabs ------------------------------------------------------------- */

.slab {
  position: relative;
  padding-block: var(--pad-seccao);
}
.slab-escuro { background: var(--grafite); color: var(--zinco); }
.slab-fundo  { background: var(--grafite-fundo); color: var(--zinco); }

/* THE HARD CUT. 2px solid rule, never a gradient, never a fade.
   If this softens, the whole idea collapses. */
.slab-zinco {
  background: var(--chapa);
  color: var(--tinta);
  border-top: 2px solid var(--linha-tinta);
  border-bottom: 2px solid var(--linha-tinta);
}
.slab-zinco .t-rotulo,
.slab-zinco .t-legenda { color: var(--tinta-rotulo); }
.slab-zinco .t-familia { color: var(--tinta); }
.slab-zinco .t-seccao  { color: var(--tinta); }

/* --- 6.6 Hairline block + corner ticks ------------------------------------
   Ticks are rationed to three block types — MISSAO, VISAO and the contact
   form panel. That rationing is what keeps them meaningful. ------------------ */

.bloco {
  position: relative;
  background: var(--painel);
  border: 1px solid var(--linha-forte);
  padding: var(--s-6);
}
.bloco--azul { border-left: 4px solid var(--azul-linha); }

.bloco--ticks::before,
.bloco--ticks::after {
  content: "";
  position: absolute;
  width: 8px;
  height: 8px;
  pointer-events: none;
  border-color: var(--zinco-mudo);
  border-style: solid;
}
.bloco--ticks::before {
  top: 6px; right: 6px;
  border-width: 1px 1px 0 0;
}
.bloco--ticks::after {
  bottom: 6px; left: 6px;
  border-width: 0 0 1px 1px;
}

/* --- 6.7 Rules ------------------------------------------------------------- */

.regra-1 { border-top: 1px solid var(--linha); }
.regra-2 { border-top: 2px solid var(--linha-tinta); }
.slab-escuro .regra-2,
.slab-fundo  .regra-2 { border-top-color: var(--linha-forte); }

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

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  min-height: 56px;
  padding-inline: var(--s-5);
  font-family: var(--ff-mono);
  font-weight: 600;
  font-size: 1rem;
  letter-spacing: 0.04em;
  text-transform: none;
  border: none;
  transition: background-color 100ms var(--ease-mec),
              transform 100ms var(--ease-mec);
}

/* Amber fill. Registered use #1 (hero phone), #3 (form submit) only. */
.btn--ambar {
  background: var(--ambar);
  color: var(--tinta);
}
.btn--ambar:hover  { background: var(--ambar-premir); }
.btn--ambar:active { background: var(--ambar-premir); transform: translateY(1px); }

/* Bordered. The vCard block. */
.btn--contorno {
  min-height: 52px;
  background: transparent;
  border: 2px solid var(--ambar);
  color: var(--zinco-vivo);
}
.btn--contorno:hover { background: rgba(239, 167, 42, 0.08); }

/* Ghost / text link with a wiping underline. */
.btn--texto {
  position: relative;
  min-height: 44px;
  padding-inline: 0;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--zinco-vivo);
  background: none;
}
.btn--texto::after {
  content: "";
  position: absolute;
  left: 0; bottom: 8px;
  width: 100%; height: 2px;
  background: var(--ambar);
  transform: scaleX(1);
  transform-origin: left;
  transition: transform var(--t-ui) var(--ease-mec);
}
.btn--texto:hover::after { transform: scaleX(0.4); }
.slab-zinco .btn--texto { color: var(--tinta); }
.slab-zinco .btn--texto::after { background: var(--ambar-tinta); }

/* --- 6.9 Tap targets ------------------------------------------------------- */

.u-alvo {                         /* 44x44 minimum, everywhere it matters */
  min-width: 44px;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* --- 6.10 Accessibility helpers -------------------------------------------- */

.u-sr {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Anchors must never land under the sticky chrome. Bound to the token,
   never a magic number. */
[id] { scroll-margin-top: var(--scroll-offset); }

/* ==========================================================================
   7. MOTION
   Scarce, and it reads as mass rather than delight.
   ========================================================================== */

/* --- 7.1 Section reveal ----------------------------------------------------
   Applied to SECTION HEADERS and the Empresa/Novidades/Contactos blocks ONLY.
   CATALOGUE ROWS NEVER ANIMATE IN — they are present and readable the instant
   they paint. Do not put data-revelar on an SKU row.

   This used to be three near-identical IntersectionObserver scripts, one per
   section, each adding a class the CSS then transitioned. It is now a
   scroll-driven animation: the browser runs it off the main thread, and the
   ninety lines of script are gone.

   No fallback is provided ON PURPOSE. The reveal is decoration: where
   animation-timeline is missing, the elements are simply there, painted, at
   full opacity — which is the correct state, not a degraded one. The
   `backwards` fill is what hides them beforehand, and it only ever applies
   inside the @supports block below.
   ------------------------------------------------------------------------- */

@media (prefers-reduced-motion: no-preference) {
  @supports ((animation-timeline: view()) and (animation-range: entry)) {

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

    [data-revelar] {
      animation: revelar auto var(--ease) backwards;
      /* Declared AFTER the shorthand: the shorthand resets the timeline. */
      animation-timeline: view();
      /* Finished well before the block reaches the middle of the screen.
         Anything still fading at reading height is delay, not motion. */
      animation-range: entry 8% entry 44%;
    }
  }
}

/* --- 7.3 COPIADO — the only transient state in the page -------------------- */

@keyframes copiado-sai {
  from { opacity: 1; }
  to   { opacity: 0; }
}

.ref-btn {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-family: var(--ff-mono);
  font-size: var(--fs-ref);
  font-weight: 500;
  letter-spacing: var(--ls-ref);
  color: var(--tinta-mudo);
  border-bottom: 1px dotted var(--tinta-mudo);
  transition: color var(--t-hover) var(--ease-mec);
}
.ref-btn:hover { color: var(--tinta); border-bottom-color: var(--tinta); }
/* Instant swap, holds 1.2s, reverts over 200ms — no transition on the way in. */
.ref-btn.copiado {
  color: var(--ambar-tinta);
  border-bottom-color: var(--ambar-tinta);
  transition: none;
}

/* --- 7.4 Filtering is a mechanical switch, not a dissolve ------------------ */

.esconder { display: none !important; }   /* synchronous, zero transition */

/* --- 7.5 Reduced motion ----------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *, *::before, *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
    scroll-behavior: auto !important;
  }

  /* The reveal is skipped entirely: §7.1 is inside
     @media (prefers-reduced-motion: no-preference), so the keyframes are never
     registered here and the blocks are painted where they stand. */
}

/* ==========================================================================
   8. PRINT — a buyer printing the catalogue for a procurement file
   ========================================================================== */

@media print {
  body { background: #fff; color: #000; }
  .slab { padding-block: var(--s-6); }
  .slab-escuro, .slab-fundo { background: #fff; color: #000; }
  .esconder { display: revert !important; }   /* print the whole catalogue */
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 0.6875rem; }
}
