/*
  Shared by every language version of the page.
  
  Extracted from the markup once there was more than one: two copies of three
  hundred lines of CSS is two copies to keep in step, and the one that drifts is
  always the one nobody is looking at.
*/

  /*
    One page, no framework, no fonts fetched, and one inline script — which
    only chooses which store badge to show. It has to open fast on a phone on a
    building's guest wifi, which is the same network the app is judged on.
  */
  :root {
    --ink: #14213d;
    --ink-soft: #47546b;
    --page: #ffffff;
    --wash: #f4f6fb;
    --line: #dfe4ef;
    --brand: #2a4b8d;
    --brand-deep: #223e77;
    --parcel: #e8a857;
    --settled: #2e6b4f;
    --space: 1.5rem;
  }

  @media (prefers-color-scheme: dark) {
    :root {
      --ink: #e8ecf6;
      --ink-soft: #a3aec4;
      --page: #10141f;
      --wash: #171d2c;
      --line: #2a3247;
      --brand: #7fa0e0;
      --settled: #7fd3a8;
    }
  }

  * { box-sizing: border-box; }

  body {
    margin: 0;
    background: var(--page);
    color: var(--ink);
    font: 16px/1.65 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
    -webkit-text-size-adjust: 100%;
  }

  .wrap { max-width: 60rem; margin: 0 auto; padding: 0 var(--space); }

  a { color: var(--brand); }

  /* Header */
  header {
    background: linear-gradient(160deg, #35599f, #223e77);
    color: #fff;
    padding: 3.5rem 0 4rem;
  }
  header a { color: #fff; }

  /* The mark on the left, the language switch pushed to the right. */
  .brand { display: flex; align-items: center; gap: 0.75rem; margin-bottom: 2.5rem; }
  .brand .lang { margin-left: auto; }

  /* A link, not a dropdown: there are two languages and naming the other one
     is shorter than asking someone to open a menu to find it. Always written
     in the language it leads to — "Tiếng Việt" is legible to someone who reads
     no English, where "Vietnamese" is not. */
  .lang {
    font-size: 0.9rem;
    padding: 0.4rem 0.8rem;
    border: 1px solid rgba(255, 255, 255, 0.4);
    border-radius: 0.5rem;
    text-decoration: none;
    white-space: nowrap;
  }
  .lang:hover, .lang:focus-visible { background: rgba(255, 255, 255, 0.14); }
  .brand img { width: 40px; height: 40px; }
  .brand span { font-weight: 600; letter-spacing: 0.01em; }

  h1 {
    font-size: clamp(2rem, 5.5vw, 3.25rem);
    line-height: 1.15;
    margin: 0 0 1rem;
    letter-spacing: -0.02em;
    max-width: 18ch;
  }

  .lede {
    font-size: clamp(1.05rem, 2.4vw, 1.3rem);
    margin: 0 0 2rem;
    max-width: 46ch;
    color: #d5deef;
  }

  .actions { display: flex; flex-wrap: wrap; gap: 0.75rem; }

  .btn {
    display: inline-block;
    padding: 0.85rem 1.5rem;
    border-radius: 0.7rem;
    text-decoration: none;
    font-weight: 600;
    border: 1px solid transparent;
  }
  .btn-primary { background: #fff; color: var(--brand-deep); }
  .btn-ghost { border-color: rgba(255,255,255,0.45); color: #fff; }

  /* A device is offered the store it can actually install from, and anything
     unrecognised is offered both. The class comes from the inline script in
     the page head. */
  .on-ios .badge-android, .on-android .badge-ios { display: none; }

  /* Store badges.
     Drawn here rather than fetched: the page makes no external request, and a
     store badge served from a third party would be the one thing on it that
     breaks behind a corporate proxy. Both stores publish official artwork and
     require it unmodified — swap these for the real files before launch. */
  .badges { display: flex; flex-wrap: wrap; gap: 0.75rem; }

  .badge {
    display: inline-flex;
    align-items: center;
    gap: 0.65rem;
    min-height: 54px;
    padding: 0.5rem 1.15rem;
    background: #000;
    color: #fff;
    border: 1px solid rgba(255, 255, 255, 0.28);
    border-radius: 0.7rem;
    text-decoration: none;
    transition: background 0.15s ease;
  }
  .badge:hover, .badge:focus-visible { background: #1b1b1b; }
  .badge svg { width: 27px; height: 27px; flex: none; }
  .badge small {
    display: block;
    font-size: 0.68rem;
    line-height: 1.25;
    opacity: 0.88;
  }
  .badge strong {
    display: block;
    font-size: 1.12rem;
    font-weight: 600;
    line-height: 1.25;
    letter-spacing: -0.01em;
  }

  /* The web view is the lesser path — it cannot record anything — so it reads
     as an aside under the two things that can. */
  .aside { margin: 1.1rem 0 0; font-size: 0.95rem; color: #c3d0e8; }
  .aside a { color: #fff; }

  /* Sections */
  section { padding: 4rem 0; }
  section.wash { background: var(--wash); }

  h2 {
    font-size: clamp(1.5rem, 3.5vw, 2rem);
    letter-spacing: -0.01em;
    margin: 0 0 0.75rem;
    max-width: 30ch;
  }

  .sub { color: var(--ink-soft); margin: 0 0 2.5rem; max-width: 58ch; }

  /* The problem, as a before/after rather than a claim. */
  .compare { display: grid; gap: 1rem; grid-template-columns: 1fr; }
  @media (min-width: 46rem) { .compare { grid-template-columns: 1fr 1fr; } }

  .card {
    background: var(--page);
    border: 1px solid var(--line);
    border-radius: 0.9rem;
    padding: 1.5rem;
  }
  .card h3 { margin: 0 0 0.5rem; font-size: 1.05rem; }
  .card p { margin: 0; color: var(--ink-soft); }
  .card .tag {
    display: inline-block;
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    margin-bottom: 0.75rem;
    color: var(--ink-soft);
  }
  .card.now { border-left: 3px solid var(--parcel); }
  .card.after { border-left: 3px solid var(--settled); }

  /* Features */
  .grid { display: grid; gap: 1.25rem; grid-template-columns: 1fr; }
  @media (min-width: 42rem) { .grid { grid-template-columns: 1fr 1fr; } }
  @media (min-width: 64rem) { .grid { grid-template-columns: repeat(3, 1fr); } }

  .feature h3 { margin: 0 0 0.4rem; font-size: 1.05rem; }
  .feature p { margin: 0; color: var(--ink-soft); }
  .feature .mark {
    width: 2.25rem; height: 2.25rem;
    border-radius: 0.6rem;
    background: var(--brand);
    color: #fff;
    display: grid; place-items: center;
    margin-bottom: 0.9rem;
    font-weight: 700;
  }

  /* Process diagrams.

     Two drawings of each: five steps in a row above the breakpoint, stacked
     below it. Switched with `display` rather than a picture element, because
     which source a browser picks is its own business and this had already gone
     wrong once on a phone — a stylesheet media query is resolved against the
     layout viewport by every engine, and the wrong one being merely hidden is
     recoverable in a way that the wrong one being *loaded* is not.

     max-width is never lifted. Whatever ends up displayed, it cannot be wider
     than the column holding it — which is the property that was missing while
     this overflowed to the right. */
  .flow { margin: 0 0 1.25rem; }

  /* No `display` here. `.flow img` is a class *and* an element, which outranks
     a bare `.flow-wide`, so setting display in this rule silently defeated the
     switch below and both drawings were shown at every width. */
  .flow img {
    width: 100%;
    max-width: 100%;
    height: auto;
    border: 1px solid var(--line);
    border-radius: 0.9rem;
  }

  /* Declared so the space is reserved before the file arrives; every stacked
     drawing shares one canvas for exactly that reason. */
  .flow .flow-tall {
    display: block;
    aspect-ratio: 440 / 850;
    /* Capped and centred: stretched across a tablet its labels come out larger
       than the prose around them. */
    max-width: min(100%, 27rem);
    margin-inline: auto;
  }

  .flow .flow-wide { display: none; aspect-ratio: 1240 / 470; }

  @media (min-width: 64rem) {
    .flow .flow-tall { display: none; }
    .flow .flow-wide { display: block; }
  }

  /* Specimen of the exported report. */
  .specimen {
    border: 1px solid var(--line);
    border-radius: 0.9rem;
    overflow: hidden;
    max-width: 44rem;
  }
  .specimen-head {
    padding: 1rem 1.25rem;
    background: var(--wash);
    border-bottom: 1px solid var(--line);
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem 1rem;
    justify-content: space-between;
    align-items: baseline;
  }
  .specimen-head span { color: var(--ink-soft); font-size: 0.875rem; }

  /* The table has a min-content width of its own; without a scroll container
     it stretches the document past the viewport on a phone and every line of
     text on the page runs off the right edge. */
  .specimen-scroll { overflow-x: auto; }
  .specimen table {
    width: 100%;
    min-width: 22rem;
    border-collapse: collapse;
    font-size: 0.925rem;
  }
  .specimen th, .specimen td {
    text-align: left;
    padding: 0.6rem 1.25rem;
    border-bottom: 1px solid var(--line);
  }
  .specimen th {
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--ink-soft);
  }
  .specimen .n { text-align: right; font-variant-numeric: tabular-nums; }
  /* A date is one thing; broken over two lines it reads as two. */
  .specimen td:first-child, .specimen th:first-child { white-space: nowrap; }
  .specimen tr.struck td { color: var(--ink-soft); text-decoration: line-through; }
  .specimen tr.struck td:first-child { text-decoration: none; }
  .specimen-note {
    margin: 0;
    padding: 1rem 1.25rem;
    color: var(--ink-soft);
    font-size: 0.9rem;
  }

  /* The privacy policy. A page of prose rather than a pitch, so the header
     collapses to a bar — a full gradient hero above a legal document delays
     the only thing the reader came for. */
  header.slim { padding: 1.75rem 0; }
  header.slim .brand { margin-bottom: 0; }

  /* Narrower than `.wrap`, and deliberately: 60rem of unbroken prose is a
     wall, and this is the one page somebody reads top to bottom. */
  .prose { max-width: 44rem; padding: 3.5rem 0 1rem; }
  .prose h1 { max-width: none; font-size: clamp(1.9rem, 4.5vw, 2.6rem); }
  .prose h2 {
    font-size: 1.2rem;
    max-width: none;
    margin: 2.75rem 0 0.6rem;
  }
  .prose p, .prose li { color: var(--ink-soft); max-width: 66ch; }
  .prose ul { padding-left: 1.2rem; }
  .prose li { margin-bottom: 0.4rem; }
  .prose .updated { font-size: 0.9rem; margin-bottom: 2.5rem; }

  /* The one claim worth reading if nothing else is. */
  .prose .headline {
    border-left: 3px solid var(--brand);
    padding-left: 1rem;
    color: var(--ink);
    font-size: 1.05rem;
  }

  footer {
    border-top: 1px solid var(--line);
    padding: 2.5rem 0 3.5rem;
    color: var(--ink-soft);
    font-size: 0.925rem;
  }
  footer .row { display: flex; flex-wrap: wrap; gap: 1.25rem; justify-content: space-between; }
