/*
 * gable-app.com, drawn like the Gable iOS app.
 *
 * Tokens come from mobile/docs/DESIGN_SYSTEM.md, with the section named next
 * to each. Where the page departs from one, the comment says why: WCAG AA
 * contrast, which a web page owes and an iOS label does not promise, or a size
 * one step up for reading long text on a desktop screen.
 */

:root {
  color-scheme: light dark;

  /* §2.1 Surface / text — light */
  --background: #f2f2f7;
  --text-primary: #0b0b0f;
  /* §2.1 textSecondary is rgba(60,60,67,.60): 3.3:1 on the background, below
     AA. Raised for text only, the way AppColors keeps `warningText` beside
     `warning` instead of darkening the shared token. 4.8:1 here. */
  --text-secondary: rgba(60, 60, 67, 0.75);
  --text-tertiary: rgba(60, 60, 67, 0.3);
  --hairline: rgba(60, 60, 67, 0.12);
  --hairline-strong: rgba(0, 0, 0, 0.16); /* §4.10; AppColors.hairlineStrong */

  /* §2.1 Glass material */
  --glass-fill: rgba(255, 255, 255, 0.7);
  --glass-stroke: rgba(0, 0, 0, 0.05);
  --glass-highlight: rgba(255, 255, 255, 0.85);

  /* §2.1 Segmented control fills */
  --segment-track: rgba(118, 118, 128, 0.12);
  --segment-active: #fff;
  --segment-shadow: 0 3px 8px rgba(0, 0, 0, 0.2), 0 0 0 0.5px rgba(0, 0, 0, 0.04);

  /* Accent. AccentColor.colorset carries no colour, so the app runs on the
     system blue — #0088FF / #0091FF as iOS 26 draws it in the paywall
     baselines. As link text it is 3.2:1 on the light background, so text
     takes the same blue darkened to 5:1. */
  --tint: #0088ff;
  --tint-text: #0066cc;

  /* Toolbar (§5.1): the page colour, translucent, over the §2.1 glass blur. */
  --bar-fill: rgba(242, 242, 247, 0.8);
  /* Pressed row (§6.4), in the segment track's grey. */
  --pressed: rgba(118, 118, 128, 0.12);

  /* §2.1 Category colours — the glyph tints come from the app's own palette. */
  --food: #ff6b6b;
  --housing: #45b7d1;
  --subscriptions: #818cf8;
  --gifts: #f59e0b;
  --salary: #22c55e;

  /* §2.3 Spacing */
  --xxs: 4px;
  --xs: 8px;
  --sm: 12px;
  --md: 16px;
  --lg: 24px;
  --xl: 32px;

  /* §2.4 Corner radii */
  --radius-card: 18px;

  /* Inside a card (§5.2: one more spacing.md). Wider on a wide screen. */
  --card-pad: var(--md);

  /* §4.6 AppListRow metrics. The horizontal inset follows the card's, so a
     card of rows and a card of text share one left edge on a wide screen. */
  --row-glyph: 36px;
  --row-gap: 14px;
  --row-inset-x: var(--card-pad);
  --row-inset-y: var(--sm);

  /* SF Pro on Apple devices, like the app; the platform face elsewhere. */
  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}

@media (prefers-color-scheme: dark) {
  :root {
    /* §2.1 Surface / text — dark. Warm near-black, never #000 (§1, rule 8). */
    --background: #0a0a0c;
    --text-primary: #f2f2f5;
    --text-secondary: rgba(235, 235, 245, 0.6); /* 6.3:1 — the token as is */
    --text-tertiary: rgba(235, 235, 245, 0.3);
    --hairline: rgba(255, 255, 255, 0.1);
    --hairline-strong: rgba(255, 255, 255, 0.16);

    --glass-fill: rgba(28, 28, 32, 0.62);
    --glass-stroke: rgba(255, 255, 255, 0.06);
    --glass-highlight: rgba(255, 255, 255, 0.05);

    --segment-track: rgba(120, 120, 128, 0.24);
    --segment-active: rgba(99, 99, 105, 0.8);

    --tint: #0091ff;
    --tint-text: #0091ff; /* 6.1:1 — no darkening needed */

    --bar-fill: rgba(10, 10, 12, 0.8);
    --pressed: rgba(120, 120, 128, 0.2);
  }
}

@media (prefers-contrast: more) {
  :root {
    --text-secondary: var(--text-primary);
    --hairline: var(--hairline-strong);
  }
}

/* ---------------------------------------------------------------- base -- */

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

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  background: var(--background);
  /* Anchors (/privacy#rights) land below the sticky toolbar. */
  scroll-padding-top: calc(52px + var(--lg));
}

body {
  margin: 0;
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  background: var(--background);
  color: var(--text-primary);
  /* §2.2 body: iOS reads long text at 17pt. */
  font: 17px/1.5 var(--font);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-wrap: break-word;
}

main {
  flex: 1 0 auto;
  padding-bottom: var(--xl);
}

p,
ul {
  margin: 0;
}

a {
  color: var(--tint-text);
  text-decoration-line: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
  text-decoration-color: color-mix(in srgb, currentColor 35%, transparent);
}

a:hover {
  text-decoration-color: currentColor;
}

/* An address is one word: never split it at its hyphen. */
a[href^="mailto:"] {
  white-space: nowrap;
}

/* The ring follows each element's own corners — capsule, row, card. */
:focus-visible {
  outline: 2px solid var(--tint);
  outline-offset: 2px;
}

/* One column for every page, sized by the text inside a card: 35rem of 17px
   SF Pro is ~70 characters a line (measured in Chrome on the policy: median 71,
   nine lines in ten at 74 or fewer; 40rem gave 79). */
.wrap {
  width: 100%;
  max-width: calc(35rem + 2 * var(--card-pad) + 2 * var(--md));
  margin: 0 auto;
  padding: 0 var(--md); /* §5.2 screen padding */
}

@media (min-width: 720px) {
  :root {
    --card-pad: var(--lg);
  }
}

/* ------------------------------------------------------------- toolbar -- */

/* §5.1 Toolbar: 52pt, sticky, translucent. */
.site-header {
  position: sticky;
  top: 0;
  z-index: 10;
  background: var(--bar-fill);
  -webkit-backdrop-filter: saturate(180%) blur(24px);
  backdrop-filter: saturate(180%) blur(24px);
  border-bottom: 0.5px solid var(--hairline);
}

/* iOS scroll-edge appearance: the bar is part of the page until content
   scrolls under it. CSS only; a browser without scroll timelines keeps the
   glass bar above at all times. The blur arrives with the fill: saturating
   the bare page would tint the band under the bar. */
@supports (animation-timeline: scroll()) {
  .site-header {
    background-color: transparent;
    border-bottom-color: transparent;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    animation: toolbar-edge linear both;
    animation-timeline: scroll(root block);
    animation-range: 0 32px;
  }
}

@keyframes toolbar-edge {
  to {
    background-color: var(--bar-fill);
    border-bottom-color: var(--hairline);
    -webkit-backdrop-filter: saturate(180%) blur(24px);
    backdrop-filter: saturate(180%) blur(24px);
  }
}

.site-header .wrap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sm);
  min-height: 52px;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  color: var(--text-primary);
  /* §2.2 toolbarTitle: SF Pro Semibold 17pt */
  font-size: 17px;
  font-weight: 600;
  text-decoration: none;
}

.brand picture,
.hero-icon {
  display: block;
  flex: none;
}

.brand img {
  display: block;
  width: 28px;
  height: 28px;
  /* The home-screen mask; the PNG itself is square, as Xcode wants it. */
  border-radius: 22.5%;
  box-shadow: 0 0 0 0.5px var(--hairline);
}

/* Navigation as the app's segmented control (§4.1, fills from §2.1). */
.nav {
  display: flex;
  gap: 2px;
  padding: 2px;
  border-radius: 999px;
  background: var(--segment-track);
}

.nav a {
  display: block;
  padding: 6px 14px;
  border-radius: 999px;
  color: var(--text-primary);
  /* §2.2 segmentText: SF Pro Semibold 13pt */
  font-size: 13px;
  font-weight: 600;
  line-height: 20px;
  text-decoration: none;
}

@media (hover: hover) {
  .nav a:hover {
    background: var(--pressed);
  }
}

.nav a[aria-current="page"] {
  background: var(--segment-active);
  box-shadow: var(--segment-shadow);
}

/* ---------------------------------------------------------- page title -- */

/* iOS large title: 34pt bold. */
.page-title {
  margin: var(--xl) 0 var(--lg);
  font-size: 34px;
  line-height: 41px;
  font-weight: 700;
  letter-spacing: 0.01em;
}

.page-title:has(+ .meta) {
  margin-bottom: var(--xxs);
}

/* The quiet line under a title — §2.2 heroCaption, one step up for the web. */
.meta {
  margin-bottom: var(--lg);
  color: var(--text-secondary);
  font-size: 15px;
}

/* --------------------------------------------------------------- cards -- */

/* §2.1 glass panel: tinted fill, 0.5pt stroke, 0.5pt highlight on top.
   No shadow — §2.6: the glass makes it unnecessary. */
.card {
  background: var(--glass-fill);
  border-radius: var(--radius-card);
  box-shadow:
    inset 0 0 0 0.5px var(--glass-stroke),
    inset 0 0.5px 0 var(--glass-highlight);
  padding: var(--card-pad);
}

.card > p + p {
  margin-top: 0.75em;
}

/* Section title above its card. §2.2 `title` (title2, semibold) is the app's
   section heading; it lines up with the text inside the card, as iOS lines up
   a section header with its cells. */
.section-title {
  margin: var(--xl) 0 var(--xs);
  padding: 0 var(--card-pad);
  font-size: 22px;
  line-height: 28px;
  font-weight: 600;
  letter-spacing: -0.01em;
  text-wrap: balance;
}

p {
  text-wrap: pretty;
}

/* Keeps a dash on the line of the word before it. */
.nowrap {
  white-space: nowrap;
}

/* Arriving from a link to a section (/privacy#rights), its card answers once. */
@media (prefers-reduced-motion: no-preference) {
  .section-title:target + .card {
    animation: arrived 1.6s ease-out;
  }
}

@keyframes arrived {
  from {
    box-shadow:
      inset 0 0 0 0.5px var(--glass-stroke),
      0 0 0 3px color-mix(in srgb, var(--tint) 40%, transparent);
  }
}

/* ----------------------------------------------------------- list rows -- */

/* §4.6 AppListRow: the row pads itself (16 / 12), so a card of rows has no
   padding of its own. Divider: 0.5pt hairline starting under the title. */
.card.rows {
  padding: 0;
  overflow: hidden;
  list-style: none;
}

.row {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--row-gap);
  padding: var(--row-inset-y) var(--row-inset-x);
}

.row + .row::before {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  left: var(--row-inset-x);
  border-top: 0.5px solid var(--hairline);
}

.row.has-glyph + .row.has-glyph::before {
  /* AppListRowMetrics.dividerInset: inset + glyph + gap */
  left: calc(var(--row-inset-x) + var(--row-glyph) + var(--row-gap));
}

.card.rows.roomy .row {
  padding: 14px var(--card-pad);
}

.card.rows.roomy .row + .row::before {
  left: var(--card-pad);
}

/* §4.6 AppListGlyph: circle at 14% of the colour, 0.5pt ring at 28%, the
   symbol at 0.48 of the circle. */
.glyph {
  flex: none;
  display: grid;
  place-items: center;
  width: var(--row-glyph);
  height: var(--row-glyph);
  border-radius: 50%;
  color: var(--glyph, var(--tint));
  background: color-mix(in srgb, var(--glyph, var(--tint)) 14%, transparent);
  box-shadow: inset 0 0 0 0.5px color-mix(in srgb, var(--glyph, var(--tint)) 28%, transparent);
}

/* The symbols are drawn on a 24-unit grid with room around them; at 22px they
   come out at the app's size — about half the disc. */
.glyph svg {
  width: 22px;
  height: 22px;
}

.glyph.food { --glyph: var(--food); }
.glyph.housing { --glyph: var(--housing); }
.glyph.subscriptions { --glyph: var(--subscriptions); }
.glyph.gifts { --glyph: var(--gifts); }
.glyph.salary { --glyph: var(--salary); }

.row-text {
  flex: 1 1 auto;
  min-width: 0;
  font-size: 16px;
  line-height: 1.4;
}

/* §2.2 rowCategory (15pt medium, tracking -0.1) and rowNote, a step up. */
.row-title {
  display: block;
  font-weight: 500;
  letter-spacing: -0.006em;
}

.row-note {
  display: block;
  margin-top: 1px;
  color: var(--text-secondary);
  font-size: 15px;
}

/* A row that goes somewhere: the whole row is the link, with RowChevron. */
.row.link .row-text {
  color: var(--text-secondary);
}

.row.link a {
  color: var(--text-primary);
  font-weight: 600;
  text-decoration: none;
  -webkit-tap-highlight-color: transparent; /* the row's own pressed state shows instead */
}

.row.link a::after {
  content: "";
  position: absolute;
  inset: 0;
}

.row.link a:focus-visible {
  outline: none;
}

.row.link:has(a:focus-visible) {
  box-shadow: inset 0 0 0 2px var(--tint);
}

.row.link:active {
  background: var(--pressed);
}

@media (hover: hover) {
  .row.link:hover {
    background: var(--pressed);
  }
}

.chevron {
  flex: none;
  width: 8px;
  height: 14px;
  color: var(--text-tertiary);
}

/* Rows that carry policy text read at the body size, like the paragraphs. */
.card.rows.roomy .row-text {
  font-size: inherit;
  line-height: inherit;
}

/* A label and what it says — "Crash reports: 30 to 90 days." The app's form
   row: §2.2 formLabel in secondary, formValue in primary. */
.pair .row-label {
  color: var(--text-secondary);
}

@media (min-width: 560px) {
  .pair .row-text {
    display: grid;
    grid-template-columns: 11rem 1fr;
    column-gap: var(--md);
  }
}

@media (max-width: 559px) {
  .pair .row-label,
  .pair .row-value {
    display: block;
  }

  .pair .row-label {
    font-size: 15px;
  }
}

/* A row whose first words say what it is about. */
.lead-in strong {
  display: block;
  margin-bottom: 2px;
  font-weight: 600;
}

/* ---------------------------------------------------------------- home -- */

/* The home page is the app's welcome screen: icon, name, one line under it. */
.hero {
  padding: clamp(48px, 9vh, 96px) 0 var(--xl);
  text-align: center;
}

.hero-icon {
  width: 96px;
  margin: 0 auto;
}

.hero-icon img {
  display: block;
  width: 96px;
  height: 96px;
  border-radius: 22.5%;
  box-shadow:
    0 0 0 0.5px var(--hairline),
    0 10px 30px rgba(0, 0, 0, 0.1);
}

/* WelcomeView sets `Gable` in largeTitle over a body-size line in secondary.
   Here the name is also the page's only heading, so it is a step larger and
   heavier; the line under it is the app's. */
.hero h1 {
  margin: var(--md) 0 var(--xs);
  font-size: 40px;
  line-height: 1.15;
  font-weight: 600;
  letter-spacing: -0.01em;
}

.lede {
  max-width: 30rem;
  margin: 0 auto;
  color: var(--text-secondary);
  font-size: 17px;
  text-wrap: balance;
}

/* ----------------------------------------------------------- not found -- */

/* §4.10 AppEmptyView: concentric discs, glyph, heading, body. */
.empty {
  padding-top: 80px;
  text-align: center;
}

.empty-art {
  display: block;
  width: 128px;
  height: 128px;
  margin: 0 auto 22px;
  color: var(--text-secondary);
}

.empty-art .outer {
  stroke: var(--hairline-strong);
}

.empty-art .inner {
  stroke: var(--hairline);
  fill: rgba(255, 255, 255, 0.03); /* AppEmptyView: white 3% in both themes */
}

.empty h1 {
  margin: 0 0 6px;
  font-size: 20px;
  line-height: 1.3;
  font-weight: 600;
  letter-spacing: -0.3px;
}

.empty p {
  max-width: 280px;
  margin: 0 auto;
  color: var(--text-secondary);
  font-size: 15px;
  line-height: 1.4;
}

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

.site-footer {
  padding: var(--lg) 0 var(--xl);
  color: var(--text-secondary);
  font-size: 13px;
  text-align: center;
}

.site-footer a {
  text-decoration: none;
}

.site-footer a:hover {
  text-decoration: underline;
}

/* --------------------------------------------------------------- print -- */

/* Paper: light whatever the screen is set to, and no panels. */
@media print {
  :root {
    color-scheme: light;
    --background: #fff;
    --text-primary: #000;
    --text-secondary: rgba(60, 60, 67, 0.85);
    --hairline: rgba(60, 60, 67, 0.25);
    --tint-text: #0066cc;
    --glass-fill: transparent;
    --glass-stroke: transparent;
    --glass-highlight: transparent;
    --card-pad: 0px;
  }

  .site-header,
  .site-footer {
    display: none;
  }
}

@media (prefers-reduced-motion: no-preference) {
  .nav a,
  .row.link {
    transition: background-color 150ms ease-out; /* §2.5 small state change */
  }
}
