/* GraySky - Developer pages (/dev/*)
   Builds on styles.css. Adds: code blocks, sidebar docs layout, pricing
   table, dashboard cards. Type rides the same system-sans stack as the
   content pages (blog/legal) so the brand reads as one product.

   Section index:
     - Tokens (custom properties)
     - Layout shell (hero, buttons)
     - Section + container
     - Split hero
     - Code blocks
     - Feature grid
     - Pricing table
     - Docs layout
     - HTTP verb pill
     - Dashboard
     - Usage bar / chart
     - Sign-in page
     - Utilities (visually-hidden, focus, callouts)
*/

/* === Tokens === */
:root {
  /* TOKENS:START dev generated by scripts/sync-tokens.py from design/tokens.json — do not edit between markers, edit the JSON and re-run */
  --dev-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Monaco, Consolas, "Liberation Mono", monospace;
  --dev-code-bg: #1a1a1a;
  --dev-code-ink: #e6e6e6;
  --dev-code-mute: #8a8a8a;
  --dev-code-keyword: #b48ead;
  --dev-code-string: #a3be8c;
  --dev-code-number: #d08770;
  --dev-code-key: #88c0d0;
  --dev-accent: #1a73e8;
  --dev-accent-hover: #1557b0;
  --dev-warn: #c0392b;
  --dev-ok: #2e7d32;
  /* TOKENS:END dev */
}

/* ---------- Layout shell ---------- */

.dev-shell { background: #fff; }

/* Topnav: the shared nav.css header, no width overrides. Since the header
   unification (2026-08-20) every surface caps the bar at --maxw-nav (80rem)
   so the brand, the actions, the content, and the footer share one gutter.
   The old `max-width: none` escape here dated from the era when the app
   surfaces ran a full-width bar; keeping it made /dev the one route whose
   header ignored the cap and misaligned with its own footer. */
/* The hand-rolled light-bar overrides that used to live here are GONE
   (2026-08-20). Light is now the shared header's default — nav.css
   `.topnav--light`, which every page but the marketing landing carries — so
   re-declaring --bar-* here only risked drifting from it. The search-pill and
   GPS rules went with them: that cluster no longer exists in any header. */
.dev-shell .topnav {
  font-family: var(--font-sans, -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Helvetica, Arial, sans-serif);
  -webkit-font-smoothing: antialiased;
}
/* Brand metrics come from the shared header (nav.css .topnav--search: 28px
   tile, 15px/600 wordmark) since 2026-08-20 — the local gap/word/mark
   overrides here only drifted from it. */
/* "API" qualifier after the header wordmark (brandSuffix="API" on the TOPNAV
   marker) — same muted recipe the old hero lockup used for its API span. */
.dev-shell .topnav .brand-suffix { font-weight: 500; color: var(--bar-ink); }

.dev-hero {
  padding: 28px var(--pad-x) clamp(56px, 9vw, 120px);
  text-align: center;
}
/* Landing hero: the brand lockup that used to ride at the top (its bottom
   margin was the breathing room above the h1) moved into the header wordmark,
   so the landing variant carries that space as top padding instead. */
.dev-hero--landing { padding-top: clamp(76px, 9vw, 136px); }
.dev-hero-eyebrow {
  display: inline-block;
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: 14px;
}
.dev-hero h1 {
  font-weight: 700;
  font-size: clamp(36px, 5.5vw, 64px);
  line-height: 1.05;
  letter-spacing: -0.02em;
  margin: 0 0 16px;
  color: var(--ink);
  text-wrap: balance;
}
.dev-hero-sub {
  font-size: clamp(17px, 1.6vw, 21px);
  line-height: 1.45;
  color: var(--ink-2);
  max-width: 720px;
  margin: 0 auto 32px;
  text-wrap: pretty;
}
.dev-hero-cta {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  justify-content: center;
}

/* Buttons follow the app language: flat solid fills, pill radius, no
   borders. Secondary/danger ride the muted component fill instead of an
   outline. */
.dev-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 44px;
  padding: 0 22px;
  border-radius: var(--radius-pill);
  font-size: 15px;
  font-weight: 500;
  text-decoration: none;
  border: 0;
  transition: background-color 120ms ease, color 120ms ease, scale 120ms ease;
  cursor: pointer;
  background: none;
}
.dev-btn:active { scale: 0.97; }
.dev-btn-primary {
  background: var(--bar-bg);
  color: #fff;
}
.dev-btn-primary:hover { background: #0a0a0a; text-decoration: none; }
.dev-btn-secondary {
  color: var(--ink);
  background: var(--bg-muted);
}
.dev-btn-secondary:hover { background: #ececec; text-decoration: none; }
.dev-btn-accent {
  background: var(--dev-accent);
  color: #fff;
}
.dev-btn-accent:hover { background: var(--dev-accent-hover); text-decoration: none; }
.dev-btn-ghost {
  color: var(--ink-2);
  background: none;
}
.dev-btn-ghost:hover { color: var(--ink); text-decoration: none; }

/* Sign-out is a <button> for semantics (it triggers an action, not navigation),
   but it lives inside the topnav and should match the surrounding link style. */
.topnav-links button.dev-btn-ghost {
  font: inherit;
  padding: 0;
  cursor: pointer;
}
.dev-btn-danger {
  color: var(--dev-warn);
  background: var(--bg-muted);
}
.dev-btn-danger:hover { background: #fdecea; text-decoration: none; }

/* Flat fills need contrast flips as they nest: muted buttons flip to white
   when they sit on a muted card/plan, and back to muted inside the white
   key rows those cards contain. */
.dev-card .dev-btn-secondary,
.dev-card .dev-btn-danger,
.dev-plan .dev-btn-secondary { background: #fff; }
.dev-card .dev-btn-secondary:hover,
.dev-plan .dev-btn-secondary:hover { background: #ececec; }
.dev-card .dev-btn-danger:hover { background: #fdecea; }
.dev-key-row .dev-btn-secondary,
.dev-key-row .dev-btn-danger { background: var(--bg-muted); }
.dev-key-row .dev-btn-secondary:hover { background: #ececec; }
.dev-key-row .dev-btn-danger:hover { background: #fdecea; }

/* ---------- Section + container ---------- */

.dev-section {
  padding: clamp(48px, 7vw, 96px) var(--pad-x);
}
.dev-container {
  max-width: var(--maxw);
  margin: 0 auto;
}
.dev-section-head {
  text-align: center;
  margin-bottom: clamp(32px, 5vw, 56px);
}
.dev-section-head h2 {
  font-weight: 700;
  font-size: clamp(28px, 3.5vw, 40px);
  letter-spacing: -0.015em;
  margin: 0 0 12px;
  text-wrap: balance;
}
.dev-section-head p {
  color: var(--ink-2);
  max-width: 640px;
  margin: 0 auto;
  font-size: 17px;
  line-height: 1.5;
  text-wrap: pretty;
}
/* A head that carries only an h2. The standard margin is sized for a head
   with a supporting line, so it opens a void when that line is absent. */
.dev-section-head--tight {
  margin-bottom: clamp(24px, 3vw, 32px);
}

/* ---------- Split hero: copy + code ---------- */

.dev-split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(24px, 4vw, 64px);
  align-items: center;
  max-width: var(--maxw);
  margin: 0 auto;
}
@media (max-width: 760px) {
  .dev-split { grid-template-columns: 1fr; }
}
.dev-split-copy h2 {
  font-weight: 700;
  font-size: clamp(26px, 3vw, 36px);
  letter-spacing: -0.015em;
  margin: 0 0 16px;
  text-wrap: balance;
}
.dev-split-copy p {
  font-size: 16px;
  line-height: 1.6;
  color: var(--ink-2);
  margin: 0 0 14px;
  text-wrap: pretty;
}
.dev-split-copy ul {
  margin: 0 0 14px;
  padding-left: 1.1em;
  color: var(--ink-2);
  line-height: 1.6;
}
.dev-split-copy li { margin-bottom: 6px; }
.dev-split-cta {
  margin-top: 18px;
  margin-bottom: 0;
}

/* ---------- Code blocks ---------- */

.dev-code {
  background: var(--dev-code-bg);
  color: var(--dev-code-ink);
  border-radius: var(--radius-8);
  padding: 18px 20px;
  font-family: var(--dev-mono);
  font-size: 13.5px;
  line-height: 1.55;
  overflow-x: auto;
  white-space: pre;
  tab-size: 2;
  -webkit-font-smoothing: antialiased;
}
.dev-code .c-key { color: var(--dev-code-key); }
.dev-code .c-str { color: var(--dev-code-string); }
.dev-code .c-num { color: var(--dev-code-number); }
.dev-code .c-kw  { color: var(--dev-code-keyword); }
.dev-code .c-mute { color: var(--dev-code-mute); }
.dev-code .c-url { color: #ebcb8b; }

.dev-code-frame {
  position: relative;
  border-radius: var(--radius-12);
  overflow: hidden;
}
.dev-code-frame-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 14px;
  background: #111;
  color: var(--dev-code-mute);
  font-family: var(--dev-mono);
  font-size: 12px;
}
.dev-code-frame-bar .dot {
  width: 11px; height: 11px; border-radius: 50%;
  background: #3a3a3a;
}
.dev-code-frame-bar .dot.r { background: #ff5f57; }
.dev-code-frame-bar .dot.y { background: #febc2e; }
.dev-code-frame-bar .dot.g { background: #28c840; }
.dev-code-frame-bar .label { margin-left: 10px; }
/* The frame supplies the chrome, so the code body sits flush under the
   title bar. `margin: 0` kills the UA <pre> margin, which otherwise
   shows as a 13px light stripe between the bar and the code. */
.dev-code-frame .dev-code { border-radius: 0; margin: 0; }

code.inline {
  font-family: var(--dev-mono);
  font-size: 0.92em;
  background: var(--bg-muted);
  padding: 2px 6px;
  border-radius: var(--radius-4);
  color: var(--ink);
}

/* ---------- Feature grid ---------- */

.dev-features {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
  max-width: var(--maxw);
  margin: 0 auto;
}
@media (max-width: 880px) { .dev-features { grid-template-columns: 1fr; } }
.dev-feature {
  padding: 24px;
  /* App-language card: flat solid muted fill, no border, no shadow. */
  border-radius: var(--radius-12);
  background: var(--bg-muted);
}
.dev-feature h3 {
  font-weight: 600;
  font-size: 20px;
  margin: 0 0 8px;
  letter-spacing: -0.01em;
  text-wrap: balance;
}
.dev-feature p {
  font-size: 14.5px;
  line-height: 1.55;
  color: var(--ink-2);
  margin: 0;
  text-wrap: pretty;
}
.dev-feature-icon {
  width: 32px; height: 32px;
  margin-bottom: 12px;
  color: var(--ink);
}

/* ---------- Pricing table ---------- */

.dev-pricing {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 12px;
  max-width: var(--maxw);
  margin: 0 auto;
}
@media (max-width: 1000px) {
  .dev-pricing { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 560px) {
  .dev-pricing { grid-template-columns: 1fr; }
}
.dev-plan {
  border-radius: var(--radius-12);
  padding: 24px 20px;
  background: var(--bg-muted);
  display: flex;
  flex-direction: column;
}
.dev-plan.featured {
  /* Featured plan steps forward on the accent blue itself (same fill as
     .dev-btn-accent / "Get a free API key") — flat, no border, no shadow.
     Everything on it flips to white ink; the CTA inverts to a white pill. */
  background: var(--dev-accent);
  color: #fff;
}
.dev-plan.featured .dev-plan-tier { color: rgba(255, 255, 255, 0.75); }
.dev-plan.featured .dev-plan-price { color: #fff; }
.dev-plan.featured .dev-plan-price .per { color: rgba(255, 255, 255, 0.75); }
.dev-plan.featured .dev-plan-included { color: rgba(255, 255, 255, 0.88); }
.dev-plan.featured .dev-plan-included strong { color: #fff; }
.dev-plan.featured ul { color: rgba(255, 255, 255, 0.88); }
.dev-plan.featured li::before { border-color: #fff; }
.dev-plan.featured .dev-btn {
  background: var(--bar-bg);
  color: #fff;
}
.dev-plan.featured .dev-btn:hover { background: #0a0a0a; }
.dev-plan-tier {
  font-size: 13px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: 6px;
}
.dev-plan-price {
  font-size: 34px;
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1;
  /* Force tabular numerics so the column of plan prices lines up across
     plans regardless of the platform's default figure style. */
  font-variant-numeric: tabular-nums lining-nums slashed-zero;
}
.dev-plan-price .per {
  font-size: 14px;
  color: var(--ink-3);
  font-weight: 400;
}
.dev-plan-included {
  margin-top: 14px;
  font-size: 14px;
  color: var(--ink-2);
  text-wrap: pretty;
}
.dev-plan-included strong { color: var(--ink); }
.dev-plan ul {
  list-style: none;
  margin: 18px 0 24px;
  padding: 0;
  font-size: 14px;
  color: var(--ink-2);
  line-height: 1.6;
}
.dev-plan li {
  padding-left: 22px;
  position: relative;
  margin-bottom: 6px;
}
.dev-plan li::before {
  content: "";
  position: absolute;
  left: 4px; top: 8px;
  width: 5px; height: 9px;
  border: solid var(--ink);
  border-width: 0 1.5px 1.5px 0;
  transform: rotate(45deg);
}
.dev-plan .dev-btn { margin-top: auto; justify-content: center; }

.dev-pricing-note {
  text-align: center;
  margin: 32px auto 0;
  font-size: 14px;
  color: var(--ink-3);
  max-width: 720px;
  line-height: 1.55;
  text-wrap: pretty;
}
.dev-pricing-note a { color: var(--dev-accent); }

/* ---------- Docs layout (sidebar + content) ---------- */

.dev-docs {
  display: grid;
  /* Content column caps at 720px — the same reading measure as the /weather
     location-detail pane (.detail-inner in weather-events.styles.css). */
  grid-template-columns: 240px minmax(0, 720px);
  justify-content: center;
  gap: clamp(24px, 4vw, 56px);
  max-width: var(--maxw);
  margin: 0 auto;
  padding: clamp(32px, 5vw, 56px) var(--pad-x);
}
@media (max-width: 900px) {
  .dev-docs { grid-template-columns: minmax(0, 720px); }
  .dev-docs-nav { position: static; }
}
.dev-docs-nav {
  position: sticky;
  top: 80px;
  align-self: start;
  font-size: 14px;
}
.dev-docs-nav h4 {
  font-size: 11.5px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin: 24px 0 8px;
  font-weight: 600;
}
.dev-docs-nav h4:first-child { margin-top: 0; }
.dev-docs-nav ul {
  list-style: none;
  padding: 0;
  margin: 0 0 8px;
}
.dev-docs-nav li { margin: 0; }
.dev-docs-nav a {
  display: block;
  padding: 6px 10px;
  color: var(--ink-2);
  border-radius: var(--radius-6);
  margin-left: -10px;
  text-decoration: none;
}
.dev-docs-nav a:hover { color: var(--ink); background: var(--bg-muted); text-decoration: none; }
.dev-docs-nav a.active {
  background: #ececec;
  color: var(--ink);
  font-weight: 500;
}

.dev-docs-content {
  min-width: 0;
}
.dev-docs-content h1 {
  font-weight: 700;
  font-size: clamp(32px, 4vw, 44px);
  letter-spacing: -0.015em;
  margin: 0 0 8px;
}
.dev-docs-content h2 {
  font-weight: 700;
  font-size: 26px;
  letter-spacing: -0.01em;
  margin: 40px 0 14px;
}
.dev-docs-content h3 {
  font-size: 17px;
  font-weight: 600;
  margin: 28px 0 8px;
}
.dev-docs-content p,
.dev-docs-content li {
  font-size: 16px;
  line-height: 1.65;
  color: var(--ink);
}
.dev-docs-content p { margin: 0 0 14px; }
.dev-docs-content ul { padding-left: 1.3em; margin: 0 0 14px; }
.dev-docs-content > .docs-eyebrow {
  font-size: 12px;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: 10px;
}
.dev-docs-content .dev-code-frame { margin: 18px 0; }

.dev-docs-content table {
  width: 100%;
  border-collapse: collapse;
  margin: 18px 0 24px;
  font-size: 14.5px;
}
.dev-docs-content th,
.dev-docs-content td {
  text-align: left;
  vertical-align: top;
  padding: 10px 14px;
}
.dev-docs-content th {
  font-weight: 600;
  color: var(--ink);
  background: var(--bg-muted);
}
/* Row separation via a barely-there zebra wash instead of hairline rules. */
.dev-docs-content tbody tr:nth-child(even) { background: var(--rule-soft); }
.dev-docs-content td code,
.dev-docs-content td > .type {
  font-family: var(--dev-mono);
  font-size: 13px;
}
.dev-docs-content td .type {
  color: var(--dev-accent);
}

/* ---------- One-page layout (dev/index.html) ---------- */
/* The merged /dev page holds the builder card inside the docs column, so
   the column widens to 880px. Prose paragraphs and lists keep the 68ch
   reading measure; tables, code frames, and the builder use the full
   column. 240 + 56 + 880 = 1176px fits inside --maxw (1280px). */
.dev-docs--wide { grid-template-columns: 240px minmax(0, 880px); }
/* The hero now sits directly on the docs column. Three paddings used to
   stack into a ~210px void: the landing hero's bottom padding (up to
   120px), the grid's top padding (up to 56px), and the first heading's
   40px top margin. Close all three. .dev-hero--landing is used on this
   page only, so tightening it touches nothing else. */
.dev-hero--landing { padding-bottom: clamp(32px, 4.5vw, 60px); }
.dev-docs--wide { padding-top: clamp(24px, 3vw, 40px); }
.dev-docs--wide .dev-docs-content > :first-child { margin-top: 0; }
@media (max-width: 900px) {
  .dev-docs--wide { grid-template-columns: minmax(0, 880px); }
  /* Repeat the static override here: the base .dev-docs-nav sticky rule
     sits after the 900px media block above, so it wins there. The
     two-class selector outranks it, and the nav must not float over the
     builder controls on a phone. */
  .dev-docs--wide .dev-docs-nav { position: static; }
}
.dev-docs--wide .dev-docs-content > p,
.dev-docs--wide .dev-docs-content > ul { max-width: var(--measure); }
/* Anchor jumps and the scroll-spy must clear the fixed topnav. */
.dev-docs-content [id] { scroll-margin-top: 96px; }

/* ---------- HTTP verb pill ---------- */

.dev-endpoint {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  background: var(--bg-muted);
  border-radius: var(--radius-8);
  font-family: var(--dev-mono);
  font-size: 14px;
  margin: 14px 0 20px;
  overflow-x: auto;
}
.dev-verb {
  display: inline-block;
  padding: 2px 8px;
  border-radius: var(--radius-4);
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: #fff;
  background: var(--dev-ok);
  text-transform: uppercase;
}
.dev-verb.post { background: #1565c0; }
.dev-verb.delete { background: var(--dev-warn); }

/* ---------- Dashboard ---------- */

.dev-dash-shell {
  display: grid;
  grid-template-columns: 220px 1fr;
  min-height: calc(100vh - 60px);
}
@media (max-width: 800px) {
  .dev-dash-shell { grid-template-columns: 1fr; }
  .dev-dash-side { display: none; }
}
.dev-dash-side {
  background: var(--bg-muted);
  padding: 24px 16px;
}
.dev-dash-side nav { display: flex; flex-direction: column; gap: 2px; }
.dev-dash-side nav a {
  padding: 8px 12px;
  border-radius: var(--radius-6);
  color: var(--ink-2);
  font-size: 14.5px;
}
.dev-dash-side nav a:hover { background: #ececec; color: var(--ink); text-decoration: none; }
.dev-dash-side nav a.active { background: #fff; color: var(--ink); font-weight: 500; }
.dev-dash-side .dev-dash-user {
  margin-top: auto;
  font-size: 12px;
  color: var(--ink-3);
  padding: 12px;
}

.dev-dash-main {
  padding: clamp(24px, 4vw, 44px);
  max-width: 980px;
  width: 100%;
  margin: 0 auto;
}
.dev-dash-main > h1 {
  font-weight: 700;
  font-size: 32px;
  letter-spacing: -0.01em;
  margin: 0 0 6px;
}
.dev-dash-main > .lead {
  color: var(--ink-2);
  margin: 0 0 28px;
  font-size: 15.5px;
}

/* Dashboard card: flat muted tile; inner tiles (kv stats, key rows,
   inputs) flip to white so the hierarchy reads without any hairlines. */
.dev-card {
  background: var(--bg-muted);
  border-radius: var(--radius-12);
  padding: 22px 24px;
  margin-bottom: 18px;
}
.dev-card-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 12px;
}
.dev-card-head h2 {
  font-weight: 600;
  font-size: 22px;
  letter-spacing: -0.01em;
  margin: 0;
}
.dev-card-head .dev-card-actions { display: flex; gap: 8px; }

.dev-kv {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 18px;
}
@media (max-width: 700px) { .dev-kv { grid-template-columns: 1fr 1fr; } }
.dev-kv > div {
  padding: 14px 16px;
  background: #fff;
  border-radius: var(--radius-8);
}
.dev-kv dt {
  font-size: 11.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: 4px;
}
.dev-kv dd {
  margin: 0;
  font-size: 26px;
  font-weight: 600;
  color: var(--ink);
}
.dev-kv dd small { color: var(--ink-3); font-size: 13px; font-weight: 400; }

.dev-key-row {
  display: grid;
  grid-template-columns: 1fr auto auto;
  gap: 12px;
  align-items: center;
  padding: 12px 14px;
  border-radius: var(--radius-8);
  margin-bottom: 8px;
  background: #fff;
}
.dev-key-row code {
  font-family: var(--dev-mono);
  font-size: 13px;
  color: var(--ink);
  user-select: all;
}
.dev-key-row .meta { font-size: 12px; color: var(--ink-3); }

.dev-form-row {
  display: flex;
  gap: 8px;
  margin-bottom: 14px;
}
.dev-input {
  flex: 1;
  height: 40px;
  padding: 0 14px;
  border: 0;
  border-radius: var(--radius-8);
  font-size: 15px;
  background: var(--bg-muted);
  min-width: 0;
}
/* Inside a (muted) dashboard card the field flips to white to stay visible. */
.dev-card .dev-input { background: #fff; }
.dev-input:focus { outline: 2px solid var(--dev-accent); outline-offset: -1px; }

.dev-flash {
  padding: 12px 14px;
  border-radius: var(--radius-8);
  margin-bottom: 14px;
  font-size: 14px;
}
.dev-flash-ok { background: #e8f5e9; color: var(--dev-ok); }
.dev-flash-err { background: #fdecea; color: var(--dev-warn); }
.dev-flash-info { background: #e3f2fd; color: var(--dev-accent-hover); }

/* ---------- Usage bar / chart ---------- */

/* Track sits a step darker than the white inner tiles so an early/low fill
   still reads as an intentional inset groove, not a stray empty bar. The
   dashboards also [hidden] the bar entirely until usage is nonzero — the
   explicit display:none guards against any future display rule beating the
   UA's [hidden] default. */
.dev-usage-bar {
  height: 10px;
  background: #ececec;
  border-radius: var(--radius-pill);
  overflow: hidden;
  margin-top: 8px;
}
.dev-usage-bar[hidden] { display: none; }
.dev-usage-bar > span {
  display: block;
  height: 100%;
  background: var(--dev-accent);
  border-radius: var(--radius-pill);
}
.dev-usage-bar.over > span { background: var(--dev-warn); }

.dev-spark {
  display: flex;
  align-items: flex-end;
  gap: 2px;
  height: 80px;
  margin-top: 12px;
}
.dev-spark > span {
  flex: 1;
  background: var(--dev-accent);
  border-radius: 2px 2px 0 0;
  opacity: 0.85;
  min-height: 2px;
}
.dev-spark > span:hover { opacity: 1; }

/* Honest empty / unavailable states — shown once data resolves, in place of
   skeletons. Never fake zeros for data we don't have. */
.dev-empty {
  margin: 0;
  color: var(--ink-3);
  font-size: 14px;
}
.dev-empty a { color: var(--dev-accent); }
/* Inside the sparkline's 80px flex box, center the note instead of
   baseline-hugging like the bars do. */
.dev-spark .dev-empty { align-self: center; margin-inline: auto; }

/* ---------- Sign-in page ---------- */

.dev-auth {
  max-width: 420px;
  margin: 0 auto;
  padding: clamp(48px, 8vw, 96px) var(--pad-x);
  text-align: center;
}
.dev-auth h1 {
  font-weight: 700;
  font-size: 32px;
  letter-spacing: -0.01em;
  margin: 0 0 10px;
}
.dev-auth p { color: var(--ink-2); margin: 0 0 24px; }
.dev-auth form { display: flex; flex-direction: column; gap: 10px; }
/* An author `display` beats the UA's [hidden] rule, so signin.html's
   `form.hidden = true` success state needs this or the form (with its
   "Sending…" button) stays visible under "Check your email." */
.dev-auth form[hidden] { display: none; }
.dev-auth .dev-btn { justify-content: center; height: 44px; }
.dev-auth .legal { font-size: 12px; color: var(--ink-3); margin-top: 24px; line-height: 1.5; }
.dev-auth .legal a { color: var(--dev-accent); }

/* ---------- Pricing comparison table ---------- */
/* Side-by-side feature matrix on /dev/pricing. Replaces ~60 inline-styled
   table cells with one rule set. The featured column (Starter) gets a
   subtle highlight via :nth-child(4). */
/* The wrap owns the rounded clip (overflow-x: auto already establishes a
   clip box), so the flat table corners round without a border. */
.dev-pricing-table-wrap { overflow-x: auto; border-radius: var(--radius-12); }
.dev-pricing-table {
  width: 100%;
  border-collapse: collapse;
  background: #fff;
  font-size: 14.5px;
  font-variant-numeric: tabular-nums lining-nums slashed-zero;
}
.dev-pricing-table thead th {
  padding: 14px 18px;
  font-weight: 600;
  text-align: center;
  background: var(--bg-muted);
}
.dev-pricing-table thead th:first-child { text-align: left; }
.dev-pricing-table tbody th {
  text-align: left;
  padding: 12px 18px;
  font-weight: 500;
  color: var(--ink);
}
.dev-pricing-table tbody td {
  padding: 12px 18px;
  text-align: center;
}
/* Row separation via zebra wash, matching the docs tables — no hairlines. */
.dev-pricing-table tbody tr:nth-child(even) { background: var(--rule-soft); }
.dev-pricing-table tbody td.muted { color: var(--ink-3); }
/* Featured column (Starter) — the 4th cell in every row counting the row
   header. Keep the highlight subtle so the table reads as one surface. */
.dev-pricing-table thead th:nth-child(4),
.dev-pricing-table tbody td:nth-child(4) {
  background: #f1f1f1;
}

/* ---------- Dev FAQ list ---------- */
/* The dev-surface variant of the .faq-item pattern. Same structural class,
   but instead of the base hairline dividers each item is a flat muted tile,
   matching the app card language. */
.dev-faq {
  max-width: 760px;
  margin: 0 auto;
  display: grid;
  gap: 12px;
}
.dev-shell .faq-item {
  border-bottom: 0;
  background: var(--bg-muted);
  border-radius: var(--radius-12);
  padding: 20px 22px;
}
.dev-shell .faq-item h3 {
  font-weight: 600;
  font-size: 18px;
  letter-spacing: -0.01em;
  margin: 0 0 8px;
  color: var(--ink);
  text-wrap: balance;
}
.dev-shell .faq-item p {
  margin: 0;
  font-size: 15px;
  line-height: 1.6;
  color: var(--ink-2);
  text-wrap: pretty;
}

/* ---------- Dark CTA section ---------- */
/* "Ready to switch?" / "Start free in 60 seconds." bottom-of-page strip
   used on /dev and /dev/pricing. Mirrors the topnav --bar-bg so the dark
   chrome reads as one element. */
.dev-cta-dark {
  background: var(--bar-bg);
  color: #d6d6d6;
}
.dev-cta-dark .dev-container { text-align: center; }
.dev-cta-dark h2 {
  font-weight: 700;
  font-size: clamp(28px, 3.5vw, 40px);
  letter-spacing: -0.015em;
  color: #fff;
  margin: 0 0 14px;
  text-wrap: balance;
}
.dev-cta-dark p {
  max-width: 580px;
  margin: 0 auto 28px;
  color: #b8b8b8;
  line-height: 1.55;
  text-wrap: pretty;
}
/* Secondary button on the dark CTA bg: flat translucent fill, no outline. */
.dev-btn-outline-light {
  background: rgba(255, 255, 255, 0.1);
  color: #fff;
}
.dev-btn-outline-light:hover {
  background: rgba(255, 255, 255, 0.18);
  text-decoration: none;
}

/* Light-gray section variant — replaces inline style="background:var(--bg-muted)". */
.dev-section--muted { background: var(--bg-muted); }
/* On a muted section the (muted) card fill flips to white so the tiles stay
   visible — the featured plan keeps its accent tint. */
.dev-section--muted .dev-feature,
.dev-section--muted .dev-plan:not(.featured),
.dev-section--muted .faq-item { background: #fff; }

/* === Utilities === */

/* Screen-reader-only text. Visually hidden but exposed to assistive tech. */
.visually-hidden {
  position: absolute;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  width: 1px;
  height: 1px;
  overflow: hidden;
  white-space: nowrap;
  margin: -1px;
  padding: 0;
  border: 0;
}

/* Keyboard-only focus ring for buttons / links inside the dev shell.
   Mouse focus stays unstyled (Apple-style); :focus-visible adds the ring
   only when the focus came from a keyboard, screen reader, or programmatic
   focus call. */
.dev-shell a:focus-visible,
.dev-shell button:focus-visible,
.dev-shell input:focus-visible,
.dev-shell [tabindex]:focus-visible {
  outline: 2px solid var(--dev-accent);
  outline-offset: 2px;
  border-radius: 4px;
}

/* Inline doc callouts (info / warn). Flat tinted tiles — the tint alone
   carries the meaning, no accent border. */
.dev-callout {
  padding: 14px 18px;
  margin: 18px 0;
  border-radius: var(--radius-10);
  background: #e3f2fd;
  font-size: 15px;
  line-height: 1.55;
}
.dev-callout.warn {
  background: #fff8e1;
}
.dev-callout a { color: var(--dev-accent); }

/* Respect users who prefer less motion: drop the button transition AND the
   press-feedback scale (the parent styles.css blanket * rule also wipes
   them, but make the intent explicit here for the dev shell). */
@media (prefers-reduced-motion: reduce) {
  .dev-btn { transition: none; }
  .dev-btn:active { scale: 1; }
}

/* ==== Skeleton loading (shared pulse) ====================================
   Same loading language as the weather SPA (see gc-skel-pulse in
   src/weather-events.styles.css): flat, solid bars at the final content's
   footprint, pulsing opacity 1 -> .5 -> 1 over 2s. No spinners, no shift. */
.skel {
  display: inline-block;
  height: 12px;
  border-radius: 6px;
  background: color-mix(in srgb, var(--ink) 8%, transparent);
}
.dev-skel-rows { display: flex; flex-direction: column; gap: 14px; padding: 4px 0; }
.dev-skel-rows .skel { height: 14px; }
@media (prefers-reduced-motion: no-preference) {
  .skel { animation: dev-skel-pulse 4s cubic-bezier(0.4, 0, 0.6, 1) infinite; }
}
@keyframes dev-skel-pulse { 50% { opacity: 0.5; } }
