/* PS5 NOR Editor — site styles.
   Dark blue ground, cyan for what matters: the signed containers hold the
   blue, nvs — the 48 KB that identifies the console — is the one cyan mark
   on the chip, and reserved, erased on a healthy dump, stays the colour of
   the ground. */

/* Self-hosted, not loaded from fonts.googleapis.com: pulling a webfont
   straight from Google's CDN hands it every visitor's IP before they have
   clicked anything, with no consent asked. The five files below are exactly
   what Google's own stylesheet would have served this page — same weights,
   same Latin-only subset, IBM Plex Sans 400 and 500 sharing one variable
   file the way Google's did too — just carried here instead of fetched
   there. To pick up a new weight or family: fetch
   fonts.googleapis.com/css2?family=... with a browser user-agent, take the
   woff2 URL from its last "latin" block per face, and drop the file in
   web/fonts/. */
@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 800;
  font-stretch: 112%;
  font-display: swap;
  src: url('fonts/archivo-800.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/plex-mono-400.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('fonts/plex-mono-500.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  font-display: swap;
  src: url('fonts/plex-sans.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 500;
  font-stretch: 100%;
  font-display: swap;
  src: url('fonts/plex-sans.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  --bg:       #0a1420;
  --surface:  #101f30;
  --ink:      #dce8f2;
  --dim:      #8ea7bd;
  --rule:     #1e3346;
  --cyan:     #45dbe8;
  --blue-dk:  #1b5480;
  --blue:     #1f6096;
  --blue-hi:  #2a7ab8;
  --slate:    #3c5468;
  --danger:   #ff6b6b;
  --caution:  #e8c445;
  --good:     #4fd48a;

  --mono: "IBM Plex Mono", ui-monospace, Consolas, monospace;
  --sans: "IBM Plex Sans", -apple-system, "Segoe UI", Roboto, sans-serif;
  --disp: "Archivo", "Helvetica Neue", Arial, sans-serif;

  --pad: clamp(1.25rem, 4vw, 3.5rem);
  --strip-h: clamp(64px, 9vw, 96px);
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.55;
  overflow-x: hidden;
  -webkit-text-size-adjust: 100%;   /* iOS inflates body text in landscape */
}

h1, h2 {
  font-family: var(--disp);
  font-weight: 800;
  font-stretch: 112%;
  letter-spacing: -0.02em;
  margin: 0;
}

code { font-family: var(--mono); font-size: 0.92em; }

main { max-width: 1080px; margin: 0 auto; }

/* ---- top bar ---- */

.topbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem;
  /* Full-bleed, but the right edge is tighter than the left: nothing lines
     up with the nav on that side, so a full --pad there only stranded the
     last link out on its own. */
  padding: 0.6rem clamp(1rem, 2vw, 1.75rem) 0.6rem var(--pad);
  border-bottom: 1px solid var(--rule);
}

.logo {
  width: 38px;
  height: 38px;
  border-radius: 50%;
}

.brand {
  font-family: var(--disp);
  font-weight: 800;
  font-stretch: 112%;
  font-size: 1.15rem;
}

.nav {
  margin-left: auto;
  display: flex;
  gap: 1.6rem;
}

.nav a {
  font-family: var(--mono);
  font-size: 0.82rem;
  color: var(--dim);
  text-decoration: none;
  padding-bottom: 2px;
  border-bottom: 1px solid transparent;
}

.nav a:hover { color: var(--ink); }
.nav a[aria-current="page"] { color: var(--ink); border-bottom-color: var(--cyan); }
.nav a:focus-visible { outline: 2px solid var(--cyan); outline-offset: 3px; }

/* ---- hero ---- */

.hero { padding: clamp(2.5rem, 7vw, 5rem) var(--pad) clamp(5rem, 9vw, 8rem); }

.eyebrow {
  margin: 0 0 1.3rem;
  font-family: var(--mono);
  font-size: 0.74rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--cyan);
}

h1 {
  font-size: clamp(1.9rem, 6vw, 4.1rem);
  line-height: 0.98;
}

/* the display face is already at its heaviest, so the emphasis is the page's
   accent colour rather than more weight */
h1 .hi {
  font-style: normal;
  color: var(--cyan);
}

.lede {
  max-width: 56ch;
  margin: 1.5rem 0 0;
  font-size: clamp(1.02rem, 1.3vw, 1.14rem);
}

/* ---- sections ---- */

.band {
  padding: clamp(1rem, 2vw, 1.4rem) var(--pad) clamp(2.5rem, 6vw, 4rem);
  border-top: 1px solid var(--rule);
}

.band h2 {
  font-size: clamp(1.5rem, 3vw, 2.1rem);
  line-height: 1.1;
}

/* ---- key features ---- */

/* Bullets rather than sentences, so the groups are independent and the grid
   is free to reflow: nothing here reads across a column. */
.feats {
  margin: 2rem 0 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
  gap: 1.9rem 2.5rem;
}

.feats h3 {
  margin: 0;
  padding-bottom: 0.6rem;
  border-bottom: 1px solid var(--rule);
  font-family: var(--mono);
  font-size: 0.82rem;
  font-weight: 500;
  color: var(--cyan);
}

.feats ul {
  margin: 0.7rem 0 0;
  padding: 0;
  list-style: none;
}

.feats li {
  position: relative;
  margin-top: 0.4rem;
  padding-left: 0.9rem;
  font-size: 0.9rem;
  line-height: 1.45;
  color: var(--dim);
}

.feats li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 4px;
  height: 4px;
  background: var(--slate);
}

/* ---- the map ---- */

.map { margin: 2.75rem 0 0; }

.strip-wrap {
  position: relative;
  padding-top: 3.4rem;   /* reserves the readout row, which is out of flow */
}

/* page-load read pass: an erased-coloured shutter retracting to the right,
   left to right in address order */
.strip-wrap::before {
  content: "";
  position: absolute;
  top: 3.4rem;
  left: 0;
  right: 0;
  height: var(--strip-h);
  z-index: 2;
  background: var(--bg);
  transform-origin: right;
  pointer-events: none;
  animation: read-pass 0.8s cubic-bezier(0.22, 0.7, 0.2, 1) 0.15s forwards;
}

@keyframes read-pass {
  from { transform: scaleX(1); }
  to   { transform: scaleX(0); }
}

.strip {
  display: flex;
  gap: 2px;
  list-style: none;
  margin: 0;
  padding: 0;
  height: var(--strip-h);
}

.seg { flex: 0 1 auto; min-width: 4px; }

/* the head is four 4 KB blocks — 0.2 % of the chip each. Widened past scale,
   which is what the resting readout says, so they can be read and pointed at */
.seg-head { min-width: 12px; }

.seg button {
  display: block;
  width: 100%;
  height: 100%;
  padding: 0;
  border: 0;
  background: var(--blue);
  color: #eaf4fb;
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: box-shadow 0.15s ease;
}

/* neither transform nor filter here: either one would make the button the
   containing block for the readout above, which is meant to span the strip */
.seg button:hover { box-shadow: 0 0 0 2px var(--cyan); }
.seg button:focus-visible { outline: 2px solid var(--cyan); outline-offset: 3px; }

.seg-head button { background: var(--blue-dk); }
.seg-slb2:nth-child(even) button {
  background: repeating-linear-gradient(
    -45deg, var(--blue) 0 5px, var(--blue-hi) 5px 10px);
}
.seg-unk button { background: var(--slate); }
.seg-nvs button { background: var(--cyan); }
.seg-res button { background: var(--bg); border: 1px solid var(--rule); color: var(--dim); }

.seg-name {
  display: block;
  padding: 0.5rem 0.6rem;
  font-family: var(--mono);
  font-size: 0.7rem;
  overflow: hidden;
  white-space: nowrap;
}

/* named in the readout instead: these are too narrow for a label */
.seg-head .seg-name,
.seg-nvs .seg-name,
.seg-slb2:nth-child(7) .seg-name,
.seg-slb2:nth-child(8) .seg-name { display: none; }

/* the readout sits above the strip, like an instrument display */

.readout {
  position: absolute;
  left: 0;
  right: 0;
  bottom: calc(var(--strip-h) + 3.1rem);
  display: grid;
  grid-template-columns: max-content max-content max-content 1fr;
  align-content: end;
  align-items: baseline;
  gap: 0.35rem 1.1rem;
  margin: 0;
  padding: 0 0 0.8rem;
  border-bottom: 1px solid var(--rule);
  color: var(--ink);   /* the readout inside a segment must not inherit its white */
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s;
}

.readout b { font-family: var(--mono); font-weight: 500; font-size: 0.86rem; }

.readout i {
  font-family: var(--mono);
  font-style: normal;
  font-size: 0.74rem;
  color: var(--cyan);
  background: var(--surface);
  padding: 0.15rem 0.45rem;
  white-space: nowrap;
}

.readout > span {
  font-size: 0.88rem;
  color: var(--dim);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}

.readout-rest { opacity: 1; }

.strip:hover ~ .readout-rest,
.strip:focus-within ~ .readout-rest { opacity: 0; }

.seg button:hover .readout,
.seg button:focus-visible .readout { opacity: 1; }

.ruler { position: relative; height: 1.6rem; margin-top: 0.75rem; }

.ruler span {
  position: absolute;
  top: 0;
  font-family: var(--mono);
  font-size: 0.68rem;
  color: var(--dim);
}

.ruler-start { left: 0; padding-left: 0.35rem; border-left: 1px solid var(--rule); }
.ruler-end  { right: 0; padding-right: 0.35rem; border-right: 1px solid var(--rule); }

figcaption {
  margin: 1.2rem 0 0;
  font-size: 0.85rem;
  color: var(--dim);
  max-width: 60ch;
}

/* ---- sideways scroll hints ---- */

/* A phone draws no scrollbar. Without this a tab strip or a table that runs
   past the window edge looks like it simply ends there — so whichever side
   still has content behind it gets an inset shadow, set by the script. */
.win-tools, .win-tabs, .m-scroll, .m-pre {
  transition: box-shadow 0.15s ease;
  -webkit-overflow-scrolling: touch;   /* momentum, not a stepwise drag, on iOS */
}

/* the two strips inside the window replica scroll without a scrollbar: a real
   toolbar does not grow one, and the edge shadow already says where it goes */
.win-tools, .win-tabs { scrollbar-width: none; -ms-overflow-style: none; }
.win-tools::-webkit-scrollbar, .win-tabs::-webkit-scrollbar { display: none; }

.edge-l { box-shadow: inset 16px 0 12px -14px #020a12; }
.edge-r { box-shadow: inset -16px 0 12px -14px #020a12; }
.edge-l.edge-r {
  box-shadow: inset 16px 0 12px -14px #020a12,
              inset -16px 0 12px -14px #020a12;
}

/* ---- tab list ---- */

.tabs {
  margin: 2rem 0 0;
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 0;
}

.tabs dt {
  font-family: var(--mono);
  font-size: 0.82rem;
  padding: 0.85rem 2rem 0.85rem 0;
  border-top: 1px solid var(--rule);
  white-space: nowrap;
}

.tabs dd {
  margin: 0;
  padding: 0.85rem 0;
  border-top: 1px solid var(--rule);
  font-size: 0.94rem;
  color: var(--dim);
}

/* ---- the nudge over the window replica ---- */

/* The tab strip below looks like part of a still, so it needs to be said in
   words that it is not. The arrow bobs to draw the eye down to the strip;
   the line fades out for good once a tab has been switched. */
.nudge {
  margin: 1.4rem 0 0;
  font-family: var(--mono);
  font-size: 0.8rem;
  color: var(--cyan);
  transition: opacity 0.4s ease;
}

.nudge.done { opacity: 0; }

/* the arrow has to land close to the strip it points at */
.nudge + .win { margin-top: 1rem; }

.nudge-arrow {
  display: inline-block;
  margin-left: 0.15rem;
  animation: nudge-bob 1.6s ease-in-out infinite;
}

@keyframes nudge-bob {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(0.22rem); }
}

/* ---- the window replica ---- */

/* A still of the program, with a working tab strip. Everything inside it is
   drawn with the site's own tokens rather than screenshotted: a picture of a
   window goes stale the day a button moves, and cannot be read aloud. */

/* The replica is a picture, not prose, and the real program's toolbar is
   fourteen controls wide — inside the 1080px measure the last two fall off the
   edge. So on a wide screen it steps out of the measure by the little the
   toolbar needs, and no further; where the measure is already the wider,
   on a phone, max() leaves it exactly where it was. The caption under it stays
   at the measure, which is where a caption belongs. */
.win {
  width: max(100%, min(100vw - 3rem, 1120px));
  margin: 2.5rem 0 0 50%;
  transform: translateX(-50%);
  background: var(--surface);
  border: 1px solid var(--rule);
  font-family: var(--sans);
}

.win-bar {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.45rem 0.6rem;
  background: var(--bg);
  border-bottom: 1px solid var(--rule);
}

.win-ico { width: 16px; height: 16px; border-radius: 50%; }
.win-title { font-size: 0.78rem; }

.win-btns { margin-left: auto; display: flex; gap: 1.1rem; color: var(--dim); }
.win-btns i { font-style: normal; font-size: 0.72rem; }

/* One row, always: a toolbar that wraps to three rows of chips stops looking
   like a toolbar, and on a phone it pushed the tab strip below the fold. Past
   the edge it scrolls, and the script marks the side that still has buttons. */
.win-tools {
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  gap: 0.3rem;
  padding: 0.55rem 0.6rem;
  border-bottom: 1px solid var(--rule);
  overflow-x: auto;
}

.m-btn {
  flex: 0 0 auto;   /* in the one-row toolbar a button overflows, never shrinks */
  padding: 0.3rem 0.5rem;
  border: 1px solid var(--rule);
  font-size: 0.7rem;
  white-space: nowrap;
}

.m-accent  { border-color: var(--cyan); color: var(--cyan); }
.m-primary { background: var(--cyan); border-color: var(--cyan); color: #06131c; }
.m-btn.m-off { color: var(--slate); }   /* the app's disabled state */
.m-sep { flex: 0 0 auto; width: 1px; align-self: stretch; background: var(--rule); margin: 0 0.3rem; }

/* the strip: the one thing in here that does something */
.win-tabs {
  display: flex;
  overflow-x: auto;
  border-bottom: 1px solid var(--rule);
}

/* ten tabs have to fit the window at full width before the strip is allowed
   to scroll, so the padding is tighter than a normal control's */
.win-tabs button {
  flex: 0 0 auto;
  padding: 0.6rem 0.52rem;
  border: 0;
  border-bottom: 2px solid transparent;
  background: none;
  color: var(--dim);
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  cursor: pointer;
}

.win-tabs button:hover { color: var(--ink); }
.win-tabs button[aria-selected="true"] { color: var(--cyan); border-bottom-color: var(--cyan); }
.win-tabs button:focus-visible { outline: 2px solid var(--cyan); outline-offset: -2px; }

.win-body { padding: 1.1rem; min-height: 23rem; }

.pane {
  display: grid;
  grid-template-columns: minmax(0, 1.25fr) minmax(0, 0.85fr);
  gap: 1.6rem;
}

.pane[hidden] { display: none; }   /* beats display:grid, which [hidden] does not */
.pane:focus-visible { outline: 2px solid var(--cyan); outline-offset: 4px; }

.say { font-size: 0.92rem; color: var(--dim); }
.say p { margin: 0 0 0.9rem; }
.say p:last-child { margin-bottom: 0; }
.say b { color: var(--ink); font-weight: 500; }
.say code { color: var(--cyan); }

/* --- the mock widgets --- */

.m-head, .m-grid {
  display: grid;
  grid-template-columns: 13px minmax(0, 1.3fr) minmax(0, 1.5fr) 2.4rem 1.7rem;
  align-items: center;
  gap: 0.35rem 0.6rem;
  font-size: 0.72rem;
}

.m-head {
  margin-bottom: 0.6rem;
  padding-bottom: 0.5rem;
  border-bottom: 1px solid var(--rule);
  color: var(--dim);
  font-size: 0.64rem;
  letter-spacing: 0.1em;
}

.m-head span:first-child { grid-column: 1 / 3; }

.m-tick { display: block; width: 12px; height: 12px; border: 1px solid var(--slate); }

.m-box {
  display: block;
  min-height: 1.45rem;
  padding: 0.18rem 0.4rem;
  background: var(--bg);
  border: 1px solid var(--rule);
  font-family: var(--mono);
  font-size: 0.7rem;
}

.m-drop { position: relative; padding-right: 1.1rem; }
.m-drop::after {
  content: "";
  position: absolute;
  right: 0.4rem;
  top: 0.62rem;
  border: 3px solid transparent;
  border-top-color: var(--dim);
}

.m-mini {
  padding: 0.1rem 0.35rem;
  border: 1px solid var(--rule);
  color: var(--cyan);
  font-family: var(--mono);
  font-size: 0.66rem;
  text-align: center;
}

.m-foot {
  display: flex;
  gap: 3rem;
  margin: 1.4rem 0 0;
  color: var(--dim);
  font-family: var(--mono);
  font-size: 0.66rem;
  letter-spacing: 0.08em;
}

.m-pre {
  margin: 0;
  padding: 0.8rem;
  background: var(--bg);
  border: 1px solid var(--rule);
  font-family: var(--mono);
  font-size: 0.7rem;
  line-height: 1.6;
  overflow-x: auto;   /* a long line scrolls in here, not in the page */
}

.m-scroll { overflow-x: auto; margin-bottom: 0.8rem; }

.m-tbl {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--mono);
  font-size: 0.68rem;
  white-space: nowrap;
}

.m-tbl th {
  padding: 0.35rem 0.7rem 0.35rem 0;
  border-bottom: 1px solid var(--rule);
  color: var(--dim);
  font-weight: 400;
  text-align: left;
}

.m-tbl td { padding: 0.3rem 0.7rem 0.3rem 0; border-bottom: 1px solid var(--bg); }

.m-cy   { color: var(--cyan); }
.m-bad  { color: var(--danger); }
.m-warn { color: var(--caution); }
.m-ok   { color: var(--good); }

.m-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem;
  margin-bottom: 0.8rem;
}

.m-lbl  { color: var(--dim); font-size: 0.72rem; }
.m-note { margin: 0.6rem 0 0; color: var(--dim); font-size: 0.7rem; }

.m-group {
  margin: 1.2rem 0 0.5rem;
  color: var(--dim);
  font-size: 0.68rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.m-line {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  padding: 0.25rem 0;
  font-size: 0.74rem;
}

.m-chk, .m-radio {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.72rem;
}

.m-chk::before, .m-radio::before {
  content: "";
  flex: 0 0 auto;
  width: 11px;
  height: 11px;
  border: 1px solid var(--slate);
}

.m-radio::before { border-radius: 50%; }
.m-chk.m-on::before { background: var(--cyan); border-color: var(--cyan); }
.m-radio.m-on::before {
  background: var(--cyan);
  border-color: var(--cyan);
  box-shadow: inset 0 0 0 2px var(--surface);
}

.m-w6  { width: 5rem; }
.m-w8  { width: 6.5rem; }
.m-w10 { min-width: 6.5rem; }
.m-w12 { width: 9rem; }
.m-w14 { min-width: 11rem; }

.win-status {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0.7rem;
  border-top: 1px solid var(--rule);
  color: var(--dim);
  font-size: 0.72rem;
}

.m-dot { flex: 0 0 auto; width: 7px; height: 7px; border-radius: 50%; background: var(--cyan); }

/* ---- currency selector ---- */

.cur {
  display: flex;
  margin-left: 1.6rem;
  border: 1px solid var(--rule);
}

.cur button {
  padding: 0.3rem 0.6rem;
  border: 0;
  background: none;
  color: var(--dim);
  font-family: var(--mono);
  font-size: 0.74rem;
  cursor: pointer;
}

.cur button + button { border-left: 1px solid var(--rule); }
.cur button:hover { color: var(--ink); }
.cur button[aria-pressed="true"] { background: var(--surface); color: var(--cyan); }
.cur button:focus-visible { outline: 2px solid var(--cyan); outline-offset: -2px; }

/* ---- pricing ---- */

.plans {
  list-style: none;
  margin: 2.25rem 0 0;
  padding: 0;
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  align-items: start;
}

.plan {
  position: relative;
  padding: 1.6rem 1.5rem 1.5rem;
  background: var(--surface);
  border: 1px solid var(--rule);
}

.plan-hi { border-color: var(--cyan); }

.plan-flag {
  position: absolute;
  top: 0;
  right: 0;
  margin: 0;
  padding: 0.25rem 0.6rem;
  background: var(--cyan);
  color: #06131c;
  font-family: var(--mono);
  font-size: 0.66rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.plan-term {
  margin: 0;
  font-family: var(--mono);
  font-size: 0.8rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--dim);
}

.plan-price {
  margin: 0.6rem 0 0;
  font-family: var(--disp);
  font-weight: 800;
  font-stretch: 112%;
  font-size: 2.9rem;
  line-height: 1;
  letter-spacing: -0.02em;
}

.plan-hi .plan-price { color: var(--cyan); }

.plan-mo {
  margin: 0.5rem 0 0;
  font-family: var(--mono);
  font-size: 0.82rem;
  color: var(--ink);
}

.plan-save {
  margin: 0.25rem 0 1.5rem;
  font-size: 0.86rem;
  color: var(--dim);
}

.btn {
  display: block;
  padding: 0.7rem 1rem;
  border: 1px solid var(--cyan);
  color: var(--cyan);
  font-family: var(--mono);
  font-size: 0.82rem;
  text-align: center;
  text-decoration: none;
  transition: background 0.15s ease, color 0.15s ease;
}

.btn:hover { background: rgba(69, 219, 232, 0.12); }

.btn-solid { background: var(--cyan); color: #06131c; }
.btn-solid:hover { background: #6ee6f0; }

.btn:focus-visible { outline: 2px solid var(--cyan); outline-offset: 3px; }

/* ---- contact ---- */

/* The address on Info, in a box of its own. Sized to hug the address rather
   than stretch across the measure, and set in mono because it is a string to
   be copied exactly, not read. */
/* One box per way of reaching us, side by side while they fit and stacked
   when they do not: each stays as wide as its own address, never stretched
   to match the other. */
.contact-row {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  margin-top: 2.25rem;
}

.contact-box {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  width: max-content;
  max-width: 100%;
  margin: 0;
  padding: 1.35rem 1.6rem;
  background: var(--surface);
  border: 1px solid var(--rule);
  font-family: var(--mono);
  font-size: clamp(1.02rem, 2.6vw, 1.5rem);
  overflow-wrap: anywhere;   /* a long address must wrap, not widen the page */
  transition: border-color 0.15s ease;
}

.contact-box:hover,
.contact-box:focus-within { border-color: var(--cyan); }

.contact-box a {
  color: var(--cyan);
  text-decoration: none;
  border-bottom: 1px solid transparent;
}

.contact-box a:hover { border-bottom-color: var(--cyan); }
.contact-box a:focus-visible { outline: 2px solid var(--cyan); outline-offset: 3px; }

/* The icon says which channel this is at a glance, so it must not compete
   with the address itself: it sits dim until the box is pointed at or the
   link is tabbed to, then lights with the border it shares. */
.contact-ico {
  flex: none;
  width: clamp(20px, 3.4vw, 26px);
  height: clamp(20px, 3.4vw, 26px);
  fill: var(--dim);
  transition: fill 0.15s ease;
}

.contact-box:hover .contact-ico,
.contact-box:focus-within .contact-ico { fill: var(--cyan); }

/* ---- the question and answer page ---- */

/* About Me is written as questions, not as a biography: the question carries
   the display face, like a section heading, and the answer is ordinary prose
   under it. The hairline between pairs is the same rule that separates every
   other section on this site. */
.qa { margin: 0; }

.qa dt {
  margin-top: 2.4rem;
  padding-top: 2.4rem;
  border-top: 1px solid var(--rule);
  font-family: var(--disp);
  font-weight: 800;
  font-stretch: 112%;
  letter-spacing: -0.02em;
  font-size: clamp(1.22rem, 2.2vw, 1.55rem);
  line-height: 1.15;
}

/* the first question sits under the hero's own rule */
.qa dt:first-child { margin-top: 0; padding-top: 0; border-top: 0; }

.qa dd {
  margin: 0.9rem 0 0;
  max-width: 62ch;
  font-size: 1rem;
  color: var(--dim);
}

.qa dd p { margin: 0 0 0.85rem; }
.qa dd p:last-child { margin-bottom: 0; }

/* the line an answer ends on is the answer: it keeps the full ink */
.qa dd p:last-child { color: var(--ink); }

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

/* The last rule on every page, and the same on all three: who made it, where
   to go, who to write to, and the two lines that have to be said out loud —
   this is nobody's official tool. It carries the page's own measure, so its
   left edge lands under the text above it rather than at the window edge. */
.foot {
  border-top: 1px solid var(--rule);
}

.foot-in {
  max-width: 1080px;
  margin: 0 auto;
  padding: clamp(1.9rem, 4vw, 2.6rem) var(--pad) clamp(2.1rem, 4vw, 2.9rem);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1.4rem 2.5rem;
}

.foot-brand { display: flex; align-items: center; gap: 0.6rem; }
.foot-ico { width: 42px; height: 42px; border-radius: 50%; }
.foot-brand .brand { font-size: 1.1rem; }

.foot-nav {
  margin-left: auto;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.6rem;
}

/* The terms are not somewhere to go, so they are not in the nav: they sit at
   the end of the footer behind a rule of their own, on every page and on no
   other part of the site. */
.foot-legal {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.6rem;
  padding-left: 1.6rem;
  border-left: 1px solid var(--rule);
}

.foot-nav a,
.foot-legal a {
  font-family: var(--mono);
  font-size: 0.8rem;
  color: var(--dim);
  text-decoration: none;
  padding-bottom: 2px;
  border-bottom: 1px solid transparent;
}

.foot-nav a:hover,
.foot-legal a:hover { color: var(--ink); border-bottom-color: var(--cyan); }

.foot-nav a:focus-visible,
.foot-legal a:focus-visible { outline: 2px solid var(--cyan); outline-offset: 3px; }

/* the page you are on is named, not linked away from */
.foot-legal a[aria-current="page"] { color: var(--ink); }

.foot-fine {
  flex-basis: 100%;
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: baseline;
  gap: 0.7rem 2rem;
  padding-top: 1.3rem;
  border-top: 1px solid var(--rule);
  color: var(--dim);
  font-size: 0.78rem;
}

.foot-fine p { margin: 0; max-width: 64ch; }
.foot-copy { font-family: var(--mono); white-space: nowrap; }

/* ---- narrow screens ---- */

/* the short segments lose their label before it starts clipping */
@media (max-width: 900px) {
  .seg-res .seg-name { display: none; }
  .pane { grid-template-columns: 1fr; gap: 1.2rem; }
  .win-body { min-height: 0; }
}

/* ---- phones ---- */

@media (max-width: 720px) {
  body { font-size: 16px; }
  :root { --strip-h: 56px; }
  .strip-wrap { padding-top: 6.2rem; }
  .seg-name { display: none; }

  /* the map is tapped here, not pointed at, and a thumb is wider than a
     partition drawn to scale: the thinnest ones are given a minimum before
     they become unhittable. The big ones absorb it — they shrink in
     proportion to their share, so the picture stays readable. */
  .seg { min-width: 10px; }
  .seg-head { min-width: 8px; }
  .seg-nvs { min-width: 15px; }

  .readout > span {
    grid-column: 1 / -1;
    white-space: normal;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
  }

  /* the toolbar scrolls rather than wraps (see .win-tools), so it costs one
     row here too — but a tighter one */
  .win-tools { padding: 0.5rem; gap: 0.3rem; }
  .m-btn { padding: 0.3rem 0.5rem; font-size: 0.7rem; }

  /* a tab has to be big enough to hit with a thumb */
  .win-tabs button { padding: 0.8rem 0.62rem; font-size: 0.7rem; }
  .win-body { padding: 0.9rem; }

  /* below ~420px the nav no longer fits beside the brand and wraps to its
     own line. margin-left:auto is kept through the wrap on purpose: the nav
     is anchored to the right edge at every width, rather than trailing the
     brand at some sizes and leaving it at others. Only the gap tightens. */
  .nav { gap: 1.15rem; }

  .qa dt { margin-top: 1.9rem; padding-top: 1.9rem; }
  .qa dd { font-size: 0.96rem; }

  /* stacked, in reading order: who, then where, then the small print */
  .foot-in { gap: 1.1rem 1.6rem; }
  .foot-nav { margin-left: 0; flex-basis: 100%; gap: 0.5rem 1.4rem; }
  .foot-legal { flex-basis: 100%; padding-left: 0; border-left: 0; gap: 0.5rem 1.4rem; }

  .tabs { grid-template-columns: 1fr; }
  .tabs dt { padding: 0.85rem 0 0.2rem; }
  .tabs dd { padding: 0 0 0.85rem; border-top: 0; }
}

/* the narrowest phones still in service, around 320-390 CSS px */
@media (max-width: 480px) {
  :root { --pad: 1rem; }
  .logo { width: 32px; height: 32px; }
  .brand { font-size: 1.02rem; }
  .nav { gap: 1rem; }
  .nav a { font-size: 0.78rem; }

  .strip-wrap { padding-top: 6.8rem; }   /* the readout wraps to more lines */
  .readout b { font-size: 0.8rem; }
  .readout > span { font-size: 0.82rem; }

  .nudge { font-size: 0.76rem; }
  .win-body { padding: 0.75rem; }

  /* the identity grid is the tightest thing on the page: the two label
     columns give up what the fixed ones cannot */
  .m-head, .m-grid {
    grid-template-columns: 13px minmax(0, 1.15fr) minmax(0, 1.35fr) 2.1rem 1.5rem;
    gap: 0.35rem 0.45rem;
    font-size: 0.68rem;
  }
  .m-foot { gap: 1.4rem; }
  .m-w14 { min-width: 8.5rem; }
  .m-w10 { min-width: 5.5rem; }
}

/* ---- touch ---- */

/* Nothing here has a pointer to hover with, so the readout has to answer a
   tap. A tapped button takes focus and keeps it until something else is
   tapped, which is exactly as long as the segment stays interesting. */
@media (hover: none) {
  .seg button:focus .readout,
  .seg button:active .readout { opacity: 1; }
  .seg button:focus { box-shadow: 0 0 0 2px var(--cyan); }
  .strip:focus-within ~ .readout-rest { opacity: 0; }

  /* a link sized for a cursor is under 20px tall — too thin for a thumb.
     The extra padding is vertical only, so the row of links still reads at
     its usual size; it just gets easier to land on. */
  .nav a, .foot-nav a, .foot-legal a { padding: 0.55rem 0; }
}

@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
  .strip-wrap::before { display: none; }
}
