/*
  Scott Morgan, portfolio
  ============================================================
  Built on the Parallax Thinking design system. Every colour, face, space and
  shadow comes from its tokens; nothing is invented here.

  The composition rules being held:
    - Daylight is home. This page never goes to night.
    - One reading per view: the hero statement leads, the board orients to it.
    - The signal is spent once per reading: the act in the hero, and the one
      figure that carries the argument in the figures band. Nowhere else.
    - Selection is structure, never the signal: tiles fill with ink, not amber.
      Amber appears in controls only as the focus ring.
    - The steady green marks live/available. It reassures, it does not summon.
    - Text sits on calm ground.

  The kit in use: the Pip mark (the moon trio), Iconoir as the one icon set,
  Badge for the tags, BigStat-style bare figures for the reading, Surface
  elevation on the tiles, and the master terrain relief as the one zone of
  atmosphere.
*/

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

/* The board's rhythm, owned in one place. The gap between the cards and the gap
   above the first one are the same number by construction, not by two values
   that happen to match and then drift. */
:root { --board-gap: var(--pt-grid-gutter); }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--pt-chart);
  color: var(--pt-ink);
  font-family: var(--pt-sans);
  font-weight: var(--pt-weight-body);
  font-size: var(--pt-fs-body);
  line-height: var(--pt-lh-body);
  -webkit-font-smoothing: antialiased;
}

.shell {
  width: 100%;
  max-width: 1120px;
  margin: 0 auto;
  padding-inline: var(--pt-space-3);
}

.skip {
  position: absolute;
  left: -9999px;
}
.skip:focus {
  left: var(--pt-space-3);
  top: var(--pt-space-3);
  z-index: 40;
  background: var(--pt-chart-card);
  color: var(--pt-ink);
  padding: var(--pt-space-1) var(--pt-space-2);
  border-radius: var(--pt-radius);
  box-shadow: var(--pt-lift-2);
}

:where(a, button, [tabindex]):focus-visible {
  outline: 2px solid var(--pt-focus);
  outline-offset: 3px;
  border-radius: var(--pt-radius-sm);
}

/* ---------- the surveyor's register ---------- */

.eyebrow {
  font-family: var(--pt-mono);
  font-size: var(--pt-fs-micro);
  font-weight: 500;
  letter-spacing: var(--pt-ls-micro);
  line-height: var(--pt-lh-micro);
  text-transform: uppercase;
  color: var(--pt-ink-faint);
  margin: 0;
}

/* ---------- hero: the one reading ---------- */

.hero {
  padding-block: var(--pt-space-10) var(--pt-space-8);
  border-bottom: var(--pt-rule) solid var(--pt-hair);
}

.hero h1 {
  font-family: var(--pt-display);
  font-weight: var(--pt-weight-display);
  font-size: clamp(32px, 6vw, var(--pt-fs-display));
  line-height: var(--pt-lh-display);
  letter-spacing: var(--pt-ls-display);
  margin: var(--pt-space-3) 0 var(--pt-space-4);
  max-width: 20ch;
  text-wrap: balance;
}

.lede {
  font-size: var(--pt-fs-body-lg);
  font-weight: var(--pt-weight-light);
  color: var(--pt-ink-muted);
  max-width: 58ch;
  margin: 0 0 var(--pt-space-2);
}
.lede-2 { margin-bottom: var(--pt-space-5); }

.hero-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--pt-space-3);
}

.status {
  display: inline-flex;
  align-items: center;
  gap: var(--pt-space-1);
  font-family: var(--pt-mono);
  font-size: var(--pt-fs-sm);
  color: var(--pt-ink-muted);
  margin: 0;
}
.steady {
  width: 8px;
  height: 8px;
  border-radius: var(--pt-radius-pill);
  background: var(--pt-steady);
  flex: none;
}

/* the one act. the signal is spent here and nowhere else on this page. */
.act {
  display: inline-flex;
  align-items: center;
  gap: var(--pt-space-1);
  background: var(--pt-act-bg);
  color: var(--pt-act-fg);
  font-family: var(--pt-sans);
  font-weight: var(--pt-weight-medium);
  font-size: var(--pt-fs-body);
  text-decoration: none;
  padding: 12px var(--pt-space-3);
  border-radius: var(--pt-radius);
  box-shadow: var(--pt-lift-2), var(--pt-face-light);
  transition: box-shadow var(--pt-dur-fast) var(--pt-ease-spring),
              transform var(--pt-dur-fast) var(--pt-ease-spring),
              background var(--pt-dur-fast) var(--pt-ease);
}
.act:hover {
  transform: translateY(-1px);
  box-shadow: var(--pt-lift-3), var(--pt-face-light);
}
.act:active {
  transform: translateY(0);
  background: var(--pt-signal-press);
  box-shadow: var(--pt-press);
  transition-duration: var(--pt-dur-press);
}

/* ---------- the terrain: one contained zone of atmosphere ----------
   Content and an instrument, never a texture behind everything. The emboss
   runs as a CSS filter in CSS pixels rather than an SVG filter in user units,
   so the shadow stays the same weight at every width. That is the fix for the
   inconsistency that made the design system's focal mode unusable. */

.plate {
  margin-top: var(--pt-space-8);
  overflow: hidden;
}

.plate-inner { position: relative; }

.terrain {
  display: block;
  width: 100%;
  height: clamp(180px, 30vw, 320px);
  border-radius: var(--pt-radius-lg);
  overflow: hidden;
  background: var(--pt-chart);
}

.terrain-layer {
  filter:
    drop-shadow(6px 9px 10px rgba(150, 162, 178, 0.5))
    drop-shadow(-2px -2px 2px rgba(255, 255, 255, 0.85));
}

.terrain-cap {
  filter: drop-shadow(4px 6px 7px rgba(150, 162, 178, 0.45));
}

/* the register is one settled line on its own strip, never floating over the
   relief. text sits on calm ground. */
.plate-register {
  margin: var(--pt-space-2) 0 0;
  font-family: var(--pt-mono);
  font-size: var(--pt-fs-micro);
  letter-spacing: var(--pt-ls-micro);
  color: var(--pt-ink-faint);
}

/* ---------- the mark ---------- */

.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

.masthead {
  padding-block: var(--pt-space-3);
  border-bottom: var(--pt-rule) solid var(--pt-hair);
}
.masthead .shell {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--pt-space-2);
}
.mark {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  color: var(--pt-ink);
}
.mark svg { display: block; flex: none; }
.mark-word {
  font-family: var(--pt-display);
  font-weight: var(--pt-weight-medium);
  font-size: 15px;
  letter-spacing: 0.04em;
}
.masthead-role {
  margin: 0;
  font-family: var(--pt-mono);
  font-size: var(--pt-fs-micro);
  letter-spacing: var(--pt-ls-micro);
  text-transform: uppercase;
  color: var(--pt-ink-faint);
}

/* ---------- the reading: three figures, no panel ----------
   The display face at scale, on the ground rather than in a card, because a
   BigStat is a bare number. The amber marks the one value that carries the
   argument, which is the brand's rule for data, and it appears once here. */

.figures {
  padding-block: var(--pt-space-8);
  background: var(--pt-chart-2);
  border-block: var(--pt-rule) solid var(--pt-hair);
}
.figures-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--pt-space-5);
  align-items: start;
}
.figure-n {
  font-family: var(--pt-display);
  font-weight: var(--pt-weight-display);
  font-size: clamp(30px, 4.4vw, var(--pt-fs-h1));
  line-height: var(--pt-lh-h1);
  letter-spacing: var(--pt-ls-display);
  margin: 0 0 var(--pt-space-1);
  font-variant-numeric: tabular-nums;
}
.figure-signal .figure-n { color: var(--pt-signal-press); }
.figure-l {
  margin: 0;
  font-size: var(--pt-fs-sm);
  color: var(--pt-ink-muted);
  max-width: 34ch;
}

/* ---------- the badge, from the design system ----------
   Micro-caps mono, 4px radius, tone inside the brand's own hues. The tone is
   meaning, not decoration: everything under Built is live and running, and the
   steady green is exactly what that is for. The amber never appears here. */

/* a piece carries as many tags as it earned, so they sit in a row that wraps
   inside the tile rather than pushing its height. */
.tags {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--pt-mono);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  border-radius: var(--pt-radius);
  padding: 4px 8px;
  line-height: 1.2;
  white-space: nowrap;
}
.badge-icon { flex: none; }
.badge-neutral {
  color: var(--pt-ink-muted);
  background: transparent;
  border: 1px solid var(--pt-hair);
}
.badge-steady {
  color: var(--pt-steady-press);
  background: var(--pt-steady-wash);
  border: 1px solid transparent;
}

/* ---------- the board ---------- */

main { padding-block: var(--pt-space-8) var(--pt-space-10); }

/* The heading sits one board-gap above the first card, so the rhythm reading
   down the section is a single number rather than two that happen to match. */
.section-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--pt-space-2);
  margin-bottom: var(--board-gap);
}
.section-note {
  font-size: var(--pt-fs-sm);
  color: var(--pt-ink-faint);
  margin: 0;
}

/* every tile is the same size, in every row. size never signals importance,
   so the grid rows are locked equal rather than left to grow with content. */
.board {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  grid-auto-rows: 1fr;
  gap: var(--board-gap);
}
.board > li { display: grid; }

.tile {
  width: 100%;
  height: 100%;
  min-height: 180px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--pt-space-2);
  text-align: left;
  background: var(--pt-chart-card);
  color: var(--pt-ink);
  border: 0;
  border-radius: var(--pt-radius);
  padding: var(--pt-space-3);
  font: inherit;
  cursor: pointer;
  box-shadow: var(--pt-lift-1);
  transition: box-shadow var(--pt-dur-fast) var(--pt-ease-spring),
              transform var(--pt-dur-fast) var(--pt-ease-spring);
}
.tile:hover {
  transform: translateY(-2px);
  box-shadow: var(--pt-lift-2);
}
.tile:active {
  transform: translateY(0);
  box-shadow: var(--pt-lift-1);
  transition-duration: var(--pt-dur-press);
}

/* the affordance lives in the object and stays out of sight until wanted */
.tile-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
}
.tile-go {
  color: var(--pt-ink-faint);
  opacity: 0;
  transform: translate(-3px, 3px);
  transition: opacity var(--pt-dur-fast) var(--pt-ease),
              transform var(--pt-dur-fast) var(--pt-ease-spring);
}
.tile:hover .tile-go,
.tile:focus-visible .tile-go { opacity: 1; transform: none; }

.tile-num {
  font-family: var(--pt-mono);
  font-size: var(--pt-fs-micro);
  letter-spacing: var(--pt-ls-micro);
  color: var(--pt-ink-faint);
  font-variant-numeric: tabular-nums;
}

.tile h3 {
  font-family: var(--pt-display);
  font-weight: var(--pt-weight-heading);
  font-size: var(--pt-fs-h4);
  line-height: var(--pt-lh-h3);
  letter-spacing: var(--pt-ls-h);
  margin: 0;
  text-wrap: balance;
}

/* ---------- the reading: one piece, opened ---------- */

.scrim {
  position: fixed;
  inset: 0;
  z-index: 20;
  background: var(--pt-scrim);
  backdrop-filter: blur(var(--pt-blur-scrim));
  animation: fade var(--pt-dur-fast) var(--pt-ease);
}
@keyframes fade { from { opacity: 0 } to { opacity: 1 } }

.panel {
  position: fixed;
  z-index: 30;
  inset: 0 0 0 auto;
  width: min(560px, 100%);
  background: var(--pt-chart-card);
  box-shadow: var(--pt-lift-plane);
  overflow-y: auto;
  animation: slide 0.32s var(--pt-parallax-ease);
}
@keyframes slide { from { transform: translateX(100%) } to { transform: translateX(0) } }

.panel-inner {
  padding: var(--pt-space-5) var(--pt-space-4) var(--pt-space-8);
  display: flex;
  flex-direction: column;
  gap: var(--pt-space-2);
}

.panel-close {
  align-self: flex-end;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: transparent;
  border: var(--pt-border);
  border-radius: var(--pt-radius);
  color: var(--pt-ink-muted);
  font-family: var(--pt-mono);
  font-size: var(--pt-fs-micro);
  letter-spacing: var(--pt-ls-micro);
  text-transform: uppercase;
  padding: var(--pt-space-1) var(--pt-space-2);
  cursor: pointer;
  margin-bottom: var(--pt-space-2);
  transition: border-color var(--pt-dur-fast) var(--pt-ease),
              color var(--pt-dur-fast) var(--pt-ease);
}
.panel-close:hover { border-color: var(--pt-ink); color: var(--pt-ink); }

/* ---------- the story ----------
   One block of markup, written into the HTML by scripts/render.mjs. It reads
   down the page with JavaScript off, and is cloned into the panel with it on,
   so there is only ever one copy of the words. */

.piece-body h4 {
  font-family: var(--pt-display);
  font-weight: var(--pt-weight-display);
  font-size: var(--pt-fs-h3);
  line-height: var(--pt-lh-h3);
  letter-spacing: var(--pt-ls-heading);
  margin: 0 0 var(--pt-space-2);
  text-wrap: balance;
}

.piece-body p {
  margin: 0 0 var(--pt-space-2);
  color: var(--pt-ink-muted);
  max-width: var(--pt-measure);
}

.piece-meta {
  font-family: var(--pt-mono);
  font-size: var(--pt-fs-micro);
  letter-spacing: var(--pt-ls-micro);
  text-transform: uppercase;
  color: var(--pt-ink-faint) !important;
  padding-top: var(--pt-space-3);
  border-top: var(--pt-rule) solid var(--pt-hair);
  margin-bottom: 0 !important;
}

/* with JavaScript, the story lives in the panel and nowhere else. the panel's
   own copy has to win, because it carries the same class. */
.js .piece-body { display: none; }
.js .panel .piece-body { display: block; }

/* without it, the board relaxes into a readable list */
.no-js .board { grid-template-columns: 1fr; }
.no-js .tile { min-height: 0; cursor: default; box-shadow: none; padding-left: 0; padding-right: 0; background: transparent; }
.no-js .tile:hover { transform: none; box-shadow: none; }
.no-js .piece { padding-bottom: var(--pt-space-5); }
.no-js .piece-body {
  background: var(--pt-chart-card);
  border-radius: var(--pt-radius);
  padding: var(--pt-space-3);
  box-shadow: var(--pt-lift-1);
}

.panel-inner h4 { font-size: var(--pt-fs-h2); line-height: var(--pt-lh-h2); }

/* ---------- footer ---------- */

.foot {
  border-top: var(--pt-rule) solid var(--pt-hair);
  background: var(--pt-chart-2);
  padding-block: var(--pt-space-8);
}

.foot-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: var(--pt-space-5);
  margin-bottom: var(--pt-space-6);
}

.foot-lines {
  list-style: none;
  margin: var(--pt-space-2) 0 0;
  padding: 0;
  display: grid;
  gap: var(--pt-space-1);
}
.foot-lines li {
  display: flex;
  align-items: center;
  gap: var(--pt-space-1);
  color: var(--pt-ink-faint);
}
.foot-lines svg { flex: none; }
.foot-lines a {
  color: var(--pt-link);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
}
.foot-lines a:hover { text-decoration-thickness: 2px; }
.foot-plain { color: var(--pt-ink-muted); margin: var(--pt-space-2) 0 0; line-height: 1.9; }

.register {
  font-family: var(--pt-mono);
  font-size: var(--pt-fs-micro);
  letter-spacing: var(--pt-ls-micro);
  text-transform: uppercase;
  color: var(--pt-ink-faint);
  padding-top: var(--pt-space-3);
  border-top: var(--pt-rule) solid var(--pt-hair);
  margin: 0;
}

/* ---------- phone first: this is the designed case ---------- */

@media (max-width: 640px) {
  :root { --board-gap: var(--pt-space-2); }

  .hero { padding-block: var(--pt-space-6) var(--pt-space-5); }
  .hero h1 { max-width: none; }
  .hero-foot { flex-direction: column; align-items: stretch; }
  .act { justify-content: center; }
  main { padding-block: var(--pt-space-6) var(--pt-space-8); }
  /* one column on the phone. two was squeezing the titles into four lines and
     leaving no room for three tags, and a tile that grows to fit breaks the
     rule that every tile is the same size. */
  .board { grid-template-columns: 1fr; }
  .tile { min-height: 0; padding: var(--pt-space-3); gap: var(--pt-space-2); }
  .tile h3 { font-size: var(--pt-fs-h4); }
  .panel { width: 100%; }
  .panel-inner { padding: var(--pt-space-4) var(--pt-space-3) var(--pt-space-6); }
  .masthead .shell { justify-content: flex-start; gap: var(--pt-space-2); }
  .masthead-role { display: none; }
  .figures { padding-block: var(--pt-space-6); }
  .figures-grid { gap: var(--pt-space-4); }
  .tile-go { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    transition-duration: 0.001ms !important;
  }
}
