/* Sunstone estate map viewer: fonts, brand tokens, the linen ground.

   Two layers, two sets of rules:
   - The page around the map follows Sunstone's house system (sunstone/brand/BRIEF.md
     and IDENTITY.md): ink on linen, Geist for UI, Geist Mono eyebrows, pills and
     double bezels, film grain, one easing curve. This is an estate surface, so its
     accent is the estate's olive.
   - The lettering on the map itself follows the printed estate map
     (estate-map/v2/_source/label2.py): EB Garamond, tracked capitals for places,
     italic for areas and water, each over a soft cream halo.

   Other sheets: map.css (stage + pins), places.css (the index of places),
   chrome.css (masthead, names switch, disclaimer), controls.css (view controls,
   the tour's button, hint), states.css (loading, error), edit.css (placement mode). */

@font-face {
  font-family: "EB Garamond";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../assets/fonts/EBGaramond-Regular.woff2") format("woff2");
}

@font-face {
  font-family: "EB Garamond";
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("../assets/fonts/EBGaramond-Italic.woff2") format("woff2");
}

@font-face {
  font-family: "Geist";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("../assets/fonts/Geist-Variable.woff2") format("woff2");
}

@font-face {
  font-family: "Geist Mono";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("../assets/fonts/GeistMono-Variable.woff2") format("woff2");
}

:root {
  /* ---- Locked brand tokens ---- */
  --ink: #14120e;
  --linen: #f6f1e7;
  --bone: #fdfbf6;
  --amber: #c8853f;
  --terracotta: #a65440;
  --olive: #4e5744;
  --haze: #dcd5c6;

  /* ---- Derived, as computed in IDENTITY.md section 4 ---- */
  --ink-90: #2b2824;
  --ink-70: #58554f;
  --ink-60: #65625c; /* the muted-text floor: lightest ink that clears AA on every ground */
  --ink-45: #7a7670; /* large text and borders that identify a control */
  --ink-30: #9c9890; /* decorative only, never text */
  --amber-800: #7c552a; /* amber as text, and the focus ring */
  --amber-soft: #e8c79b;
  --terracotta-700: #864535;
  --olive-700: #414838;
  --shell: #eae4d8;
  --hairline: #dfdbd1; /* ink at 10% over linen */
  --hairline-strong: #cdc9c0; /* ink at 18% over linen: the bezel's ring */

  /* ---- The estate's accent (the live site's [data-property="estate"]) ---- */
  --accent: #6b7559;
  --accent-text: #3f4735;
  --accent-deep: var(--olive);

  /* ---- Type ---- */
  --font-sans: "Geist", ui-sans-serif, system-ui, sans-serif;
  --font-mono: "Geist Mono", ui-monospace, monospace;

  /* ---- The printed map's lettering (label2.py): used on the model only ---- */
  --font-map: "EB Garamond", "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, serif;
  --map-ink: #2e2018; /* place names */
  --map-ink-area: #584631; /* areas, deliberately quieter */
  --map-ink-water: #2f4650; /* water */
  --logo-charcoal: #333; /* the wordmark's approved charcoal */

  /* ---- Motion: transform and opacity only, on the house curve ---- */
  --ease-estate: cubic-bezier(0.32, 0.72, 0, 1);
  --ease-rise: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-exit: cubic-bezier(0.4, 0, 1, 1);
  --dur-1: 120ms;
  --dur-2: 200ms;
  --dur-3: 320ms;
  --dur-4: 480ms;
  --dur-5: 720ms;
  --dur-6: 1100ms;

  /* ---- Shape ---- */
  --radius-shell: 2rem;
  --radius-core: 1.625rem;
  --radius-shell-sm: 1.25rem;
  --radius-core-sm: 0.875rem;
  --bezel-ring: inset 0 0 0 1px rgb(20 18 14 / 0.08);
  --bezel-shell: rgb(20 18 14 / 0.045);
  --bezel-core-shadow: inset 0 1px 0 rgb(255 255 255 / 1), 0 28px 70px -36px rgb(20 18 14 / 0.3);
  --focus-ring: 0 0 0 2px var(--linen), 0 0 0 4px var(--amber-800), 0 0 0 7px rgb(200 133 63 / 0.22);

  /* ---- Layout ---- */
  --edge: clamp(16px, 2.4vw, 32px);
  /* The foot of the page: the disclaimer sits on --foot, the index of places and
     the view controls share the row above it. */
  --foot: calc(var(--edge) * 0.7 + env(safe-area-inset-bottom, 0px));
  --foot-row: calc(var(--foot) + 34px);
  --foot-side: 172px; /* width kept free either side of the index for the view controls */
  --grain-opacity: 0.045;

  /* A name on the model sits over paint of any colour, so it keeps the printed
     map's cream halo: a stroke painted under the fill does the dilate, these
     shadows the blur. */
  --halo: #f7f1e3;
  --halo-glow: 0 0 2px var(--halo), 0 0 4px var(--halo), 0 0 6px var(--halo),
    0 0 9px var(--halo), 0 0 13px var(--halo);

  color-scheme: light;
}

html,
body {
  height: 100%;
  margin: 0;
}

html {
  background: var(--linen);
}

body {
  position: fixed;
  inset: 0;
  overflow: hidden;
  color: var(--ink);
  font-family: var(--font-sans);
  font-feature-settings: "ss01", "cv01";
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  -webkit-text-size-adjust: 100%;
  background: var(--linen);
}

/* The brand's eyebrow: Geist Mono, 10px, uppercase, tracked 0.2em. */
.eyebrow {
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 500;
  line-height: 1.6;
  letter-spacing: 0.2em;
  text-transform: uppercase;
}

::selection {
  background: var(--amber);
  color: var(--bone);
}

/* ---- Ground: the warm bloom behind the subject, and the film grain ------- */

.ground {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}

/* Aventurescence, layer 1: an off-centre warm radial sitting behind the slab. */
.ground::before {
  content: "";
  position: absolute;
  inset: -10%;
  background: radial-gradient(52% 44% at 50% 50%,
    rgb(200 133 63 / 0.2) 0%,
    rgb(200 133 63 / 0.1) 36%,
    rgb(166 84 64 / 0.035) 64%,
    rgb(246 241 231 / 0) 100%);
}

/* Film grain: one fixed layer over the whole page, model included, so the render
   and the paper share one surface. Never on anything that scrolls. */
body::after {
  content: "";
  position: fixed;
  z-index: 30;
  inset: 0;
  pointer-events: none;
  opacity: var(--grain-opacity);
  mix-blend-mode: multiply;
  background-image: url("../assets/brand/grain.svg");
  background-size: 220px 220px;
}

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

/* Four 44px controls on a touch screen. */
@media (pointer: coarse) {
  :root {
    --foot-side: 204px;
  }
}

@media (max-width: 640px) {
  :root {
    --foot-row: calc(var(--foot) + 50px); /* the disclaimer wraps to two lines */
    --foot-side: 0px; /* no controls beside the index: upright, they move to the top; on its side, the index moves to the left */
  }
}

/* On its side a phone keeps the controls in the foot row (controls.css). The
   disclaimer fits on one line from 480px wide; under that its two lines are
   set close enough to fit as well (chrome.css), so no height leaves the map. */
@media (max-height: 500px) and (orientation: landscape) {
  :root {
    --foot-row: calc(var(--foot) + 34px);
  }
}

@media (max-height: 500px) and (orientation: landscape) {
  :root {
    /* A narrow window on its side stands the tour's button and the index in a
       column at the left (controls.css, places.css), from here: 15px under the
       wordmark, which is 17px tall there (chrome.css), as the tags are on a
       wide screen. */
    --column-top: calc(var(--edge) + 32px + env(safe-area-inset-top, 0px));
  }
}

@media (prefers-reduced-transparency: reduce) {
  body::after {
    display: none;
  }

  .ground::before {
    opacity: 0.4;
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
    transition-delay: 0s !important;
    animation: none !important;
  }
}
