/* =========================================================================
   ZWARTBAERD — BASE
   Document defaults, faces, and the ground layer stacks.
   No components. No sections.
   ========================================================================= */

/* -------------------------------------------------------------------------
   1 · FACES                                                  Vol. I §4.7

   Self-hosted WOFF2, subset to Latin + Latin Extended-A (Dutch needs ĳ ë é).
   Four files maximum, ≤180 KB total.

   FONT SOURCING NOTE — must be resolved before launch:
   Vol. I §4.2 requires REAL small caps (smcp), not text-transform at reduced
   size. The Google Fonts distribution of EB Garamond does not ship an smcp
   feature. The self-hosted subset must be built from a source that carries
   it (the upstream EB Garamond project, or an EB Garamond SC cut declared
   as a separate face). Until then, small caps render as a synthesised
   fallback and will have the wrong stroke weight.
   ------------------------------------------------------------------------- */

@font-face {
  font-family: "EB Garamond";
  src: url("../assets/fonts/eb-garamond-var.woff2") format("woff2-variations");
  font-weight: 400 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "EB Garamond";
  src: url("../assets/fonts/eb-garamond-var-italic.woff2") format("woff2-variations");
  font-weight: 400 500;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: "Spectral";
  src: url("../assets/fonts/spectral-400.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Spectral";
  src: url("../assets/fonts/spectral-400-italic.woff2") format("woff2");
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}

/* Metric-matched fallbacks so the swap causes no layout shift (CLS ≤ 0.02).
   VALUES ARE PROVISIONAL — remeasure against the real WOFF2 files. */
@font-face {
  font-family: "EB Garamond Fallback";
  src: local("Georgia"), local("Times New Roman");
  size-adjust: 92%;
  ascent-override: 88%;
  descent-override: 26%;
  line-gap-override: 0%;
}
@font-face {
  font-family: "Spectral Fallback";
  src: local("Georgia"), local("Times New Roman");
  size-adjust: 97%;
  ascent-override: 92%;
  descent-override: 28%;
  line-gap-override: 0%;
}


/* -------------------------------------------------------------------------
   2 · RESET — minimal
   ------------------------------------------------------------------------- */

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

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

body,
h1, h2, h3, p, figure, blockquote, ul, ol, dl, dd {
  margin: 0;
}

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

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

button, input, select, textarea { font: inherit; color: inherit; }

:where(a) { color: inherit; }


/* -------------------------------------------------------------------------
   3 · DOCUMENT                                              Vol. XI §4
   ------------------------------------------------------------------------- */

html {
  font-size: 100%;                        /* 16px root; never override */
  scroll-behavior: smooth;
}

/* In-page navigation targets. The offset clears the nav when it returns on
   upward scroll, so an anchored heading is never hidden beneath it. */
:target,
[id="het-huis"], [id="over-zwartbaerd"], [id="handelswaeren"],
[id="het-ambacht"], [id="de-voorwaarden"], [id="contact"] {
  scroll-margin-block-start: var(--nav-height-sm);
}

@media (min-width: 64rem) {
  :target,
  [id="het-huis"], [id="over-zwartbaerd"], [id="handelswaeren"],
  [id="het-ambacht"], [id="de-voorwaarden"], [id="contact"] {
    scroll-margin-block-start: var(--nav-height);
  }
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

body {
  font-family: var(--face-text);
  font-size: var(--t-body);
  line-height: var(--lh-body);
  font-feature-settings: var(--num-prose);   /* old-style figures, document default */
  color: var(--text);
  background-color: var(--surface);
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;                        /* the frontispiece image bleeds */
}

/* Hanging punctuation — Vol. XI §13.4. Safari only at present; harmless
   elsewhere and correct the day the others ship it. */
p, blockquote { hanging-punctuation: first last; }

h1, h2, h3 {
  font-family: var(--face-display);
  font-weight: 400;                         /* bold is banned. Vol. I §4.6 */
  text-wrap: balance;
  hyphens: none;
}

em, i { font-style: italic; }
strong, b { font-weight: 400; font-style: italic; }  /* emphasis is italic */


/* -------------------------------------------------------------------------
   4 · UTILITY CLASSES — typography roles
   ------------------------------------------------------------------------- */

.smallcap {
  font-family: var(--face-display);
  font-variant-caps: small-caps;
  font-feature-settings: var(--smallcaps);
  font-size: var(--t-label);
  line-height: var(--lh-label);
  letter-spacing: var(--tr-smallcap);
}

.tabular { font-feature-settings: var(--num-tabular); }

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}


/* -------------------------------------------------------------------------
   5 · FOCUS                                                 Vol. XI §9
   Never removed. Never replaced by the hover style. Tested against all
   four grounds in all four lighting states.
   ------------------------------------------------------------------------- */

:focus { outline: none; }

:focus-visible {
  outline: var(--focus-ring);
  outline-offset: var(--focus-offset);
  box-shadow: 0 0 0 calc(var(--focus-offset) + 2px) var(--ink-iron);
}


/* -------------------------------------------------------------------------
   6 · SKIP LINK                                            Vol. III §2
   First focusable element on the page.
   ------------------------------------------------------------------------- */

.skip-link {
  position: absolute;
  top: var(--sp-2);
  left: var(--sp-4);
  z-index: 100;
  transform: translateY(-200%);
  padding: var(--sp-3) var(--sp-5);
  background: var(--ground-parchment);
  color: var(--ink-iron);
  text-decoration: none;
}
.skip-link:focus-visible { transform: translateY(0); }


/* -------------------------------------------------------------------------
   7 · THE SHEET                                            Vol. XI §5.2
   Paper does not stretch. Beyond 1440 the desk grows and the sheet
   does not; between 1400 and 1440 the desk margin compresses to 48px
   before the sheet begins to shrink.
   ------------------------------------------------------------------------- */

.sheet {
  width: min(100% - (var(--page-margin) * 2), var(--sheet-max));
  margin-inline: auto;
}

@media (min-width: 64rem) {
  .sheet { width: min(100% - 6rem, var(--sheet-max)); }
}


/* -------------------------------------------------------------------------
   8 · GROUND LAYER STACKS                                Vol. IX §3.1–3.4

   Every surface is an ordered stack. No surface is "a colour with a
   texture on it".

     ebony:  content · vignette · wash · grain 3% · base
     oak:    content · vignette · wash · grain 5% · base

   The wash is already folded into --surface via color-mix, so it does not
   appear as a layer here. Grain and vignette are pseudo-elements because
   background-image cannot carry per-layer opacity.
   ------------------------------------------------------------------------- */

.ground {
  position: relative;
  background-color: var(--surface);
  isolation: isolate;
}

.ground > * { position: relative; z-index: 1; }

/* Grain */
.ground::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image: var(--tex-wood);
  background-size: var(--tile-wood) var(--tile-wood);
  background-repeat: repeat;
  mix-blend-mode: var(--tex-blend);
  opacity: var(--ground-grain-alpha, 0);
}

[data-ground="oak"]   { --ground-grain-alpha: var(--alpha-wood-oak); }
[data-ground="ebony"] { --ground-grain-alpha: var(--alpha-wood-eb); }

/* Vignette — one candle, upper left, 40°. Origin is shared by every
   dark section on the site.                                Vol. XI §7 */
.ground--dark::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background: radial-gradient(
    ellipse 125% 125% at var(--light-origin-x) var(--light-origin-y),
    rgb(var(--shadow-ink) / 0) 0%,
    rgb(var(--shadow-ink) / calc(var(--vignette-alpha) * 0.45)) 55%,
    rgb(var(--shadow-ink) / var(--vignette-alpha)) 100%
  );
  animation: candle-flicker 6.5s ease-in-out infinite;
  animation-play-state: var(--flicker-play);
}

/* Near-subliminal. ±1.5% at Nacht. If it is noticed as an animation,
   it is too strong.                                        Vol. II §10.3 */
@keyframes candle-flicker {
  0%   { opacity: 1;     }
  11%  { opacity: 0.988; }
  19%  { opacity: 1;     }
  37%  { opacity: 0.991; }
  44%  { opacity: 0.999; }
  58%  { opacity: 0.986; }
  71%  { opacity: 1;     }
  83%  { opacity: 0.993; }
  100% { opacity: 1;     }
}

@media (prefers-reduced-motion: reduce) {
  .ground--dark::after { animation: none; }
}

/* Mobile: a radial vignette on a tall narrow section reads as a dark
   band, so it becomes linear.                              Vol. V §10 */
@media (max-width: 43.6875rem) {
  .ground--dark::after {
    background: linear-gradient(
      to bottom,
      rgb(var(--shadow-ink) / 0) 0%,
      rgb(var(--shadow-ink) / calc(var(--vignette-alpha) * 0.35)) 60%,
      rgb(var(--shadow-ink) / var(--vignette-alpha)) 100%
    );
  }
}


/* -------------------------------------------------------------------------
   9 · THE PAPER STACK                                    Vol. IX §3.1–3.2

     content
     tide line     edge only, 3%, non-tiling, one asset mirrored
     foxing        non-tiling, 4–6% by state, three assets A/B/C
     laid paper    SVG line structure + fibre, 3.5%
     base          #E4D8BE / #EFE6D2

   .ground carries the dark wood surfaces; .paper carries the light ones.
   They use the same pseudo-element slots, so an element takes one or the
   other — never both.
   ------------------------------------------------------------------------- */

.paper {
  position: relative;
  isolation: isolate;
  background-color: var(--surface);
}
.paper > * { position: relative; z-index: 1; }

/* Laid structure — chain lines every 94px, laid lines every 3.8px. */
.paper::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image: url("../assets/svg/laid.svg");
  background-size: 5.875rem 0.2375rem;       /* 94 × 3.8 */
  background-repeat: repeat;
  mix-blend-mode: var(--tex-blend);
  opacity: var(--alpha-laid);
}

@media (max-width: 43.6875rem) {
  .paper::before { background-size: 4.40625rem 0.178125rem; }  /* 0.75× */
}

/* Foxing — non-tiling, the only state-variable texture. */
.paper::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image: var(--paper-foxing, none);
  background-size: 100% auto;
  background-position: left top;
  background-repeat: no-repeat;
  mix-blend-mode: var(--tex-blend);
  opacity: var(--alpha-foxing);
}

/* Three assets so no two parchment sections age identically. An evenly
   aged page reads as wallpaper; unevenly aged reads as an object. */
.paper--a { --paper-foxing: var(--tex-foxing-a); }   /* Voorrede — light, upper-left */
.paper--b { --paper-foxing: var(--tex-foxing-b); }   /* De Waren / De Stoffen — lower edge */
.paper--c { --paper-foxing: var(--tex-foxing-c); }   /* Scheepsjournaal — heaviest, right margin */

/* Tide line — one asset, mirrored for its second use in § 8.
   Crop, never stretch: the irregular inner boundary smears. */
.paper__tide {
  position: absolute;
  inset-block-start: 0;
  inset-inline-start: 0;
  z-index: 0;
  width: 21.25rem;                            /* 340 */
  max-width: 30%;
  height: 125rem;                             /* 2000 — crops, does not stretch */
  max-height: 100%;
  pointer-events: none;
  background-image: var(--tex-tide);
  background-size: 21.25rem 125rem;
  background-repeat: no-repeat;
  mix-blend-mode: var(--tex-blend);
  opacity: var(--alpha-tide);
}


