/*
  Switchboard — the site.

  Deliberately the app's palette, not a separate brand: the screenshots are most of the
  page, and a site in different colours would make its own product look like a stock photo
  dropped into someone else's template.

  Hand-written CSS, no build step and no framework. The whole site is three files, and a
  toolchain to produce three files is a toolchain to maintain forever.
*/

:root {
  --surface:      #0e0e12;
  --card:         #171719;
  --card-hover:   #222228;
  --stroke:       #26262c;
  --text:         #f2f2f4;
  --text-2:       #a8a8b3;
  --text-3:       #6e6e7a;
  --accent:       #4c8bf5;
  --accent-ink:   #ffffff;
  --warning:      #d9a03c;

  --max:          1120px;
  --radius:       14px;
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--surface);
  color: var(--text);
  font: 400 16px/1.65 "Segoe UI", system-ui, -apple-system, sans-serif;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 { line-height: 1.2; margin: 0 0 .5em; letter-spacing: -.02em; }
h1 { font-size: clamp(2.1rem, 5vw, 3.4rem); font-weight: 700; }
h2 { font-size: clamp(1.5rem, 3vw, 2.1rem); font-weight: 650; }
h3 { font-size: 1.05rem; font-weight: 620; }

p { margin: 0 0 1em; }

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

code, kbd {
  font-family: "Cascadia Mono", ui-monospace, Consolas, monospace;
  font-size: .87em;
}

code { color: var(--text-2); background: var(--card); padding: .12em .4em; border-radius: 5px; }

/* A SHA-256 is 64 characters with no spaces, so it must be allowed to break mid-string
   or it forces a horizontal scrollbar on a phone. */
code.hash { word-break: break-all; font-size: .82em; letter-spacing: .02em; }

kbd {
  background: var(--card-hover);
  border: 1px solid var(--stroke);
  border-bottom-width: 2px;
  border-radius: 5px;
  padding: .1em .45em;
  color: var(--text);
}

main { max-width: var(--max); margin: 0 auto; padding: 0 24px; }

section { padding: 72px 0; }

/* ── Nav ─────────────────────────────────────────────────────────────────── */

.nav {
  max-width: var(--max);
  margin: 0 auto;
  padding: 20px 24px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--text);
  font-weight: 650;
  font-size: 1.05rem;
}
.brand:hover { text-decoration: none; }
.brand img { border-radius: 7px; }

.nav nav { display: flex; align-items: center; gap: 22px; }
.nav nav a { color: var(--text-2); font-size: .93rem; }
.nav nav a:hover { color: var(--text); text-decoration: none; }

.nav .coffee {
  color: var(--text);
  background: var(--card-hover);
  border: 1px solid var(--stroke);
  padding: 7px 14px;
  border-radius: 999px;
}
.nav .coffee:hover { background: #2e2e36; }

/* ── Hero ────────────────────────────────────────────────────────────────── */

.hero {
  display: grid;
  grid-template-columns: 1.05fr .95fr;
  gap: 56px;
  align-items: center;
  padding-top: 40px;
}

.lede { font-size: 1.15rem; color: var(--text-2); max-width: 34em; }

.cta { margin-top: 34px; }

.download {
  display: inline-flex;
  flex-direction: column;
  gap: 2px;
  background: var(--accent);
  color: var(--accent-ink);
  padding: 15px 30px;
  border-radius: 12px;
  font-weight: 650;
  /* The shadow is the accent colour rather than black: it reads as the button glowing
     rather than as a card floating, which is the only element on the page that should. */
  box-shadow: 0 8px 26px -8px rgba(76, 139, 245, .75);
  transition: transform .12s ease, box-shadow .12s ease;
}
.download:hover {
  text-decoration: none;
  transform: translateY(-1px);
  box-shadow: 0 12px 30px -8px rgba(76, 139, 245, .9);
}
.download-main { font-size: 1.06rem; }
.download-sub { font-size: .8rem; font-weight: 450; opacity: .85; }

.cta-note { margin-top: 14px; font-size: .87rem; color: var(--text-3); }

.hero-shot img {
  width: 100%;
  max-width: 340px;
  height: auto;
  display: block;
  margin: 0 auto;
  /* No border or background: the screenshot already has the app's own rounded corners
     and drop shadow baked in, so framing it would draw a second frame. */
}

/* ── Features ────────────────────────────────────────────────────────────── */

.features h2 { text-align: center; margin-bottom: 44px; }

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 18px;
}

.grid article {
  background: var(--card);
  border: 1px solid var(--stroke);
  border-radius: var(--radius);
  padding: 24px 24px 8px;
}

.grid h3 { color: var(--text); }
.grid p { color: var(--text-2); font-size: .95rem; }

/* ── Screenshot sections ─────────────────────────────────────────────────── */

.shots { text-align: center; }
.shots.alt { border-top: 1px solid var(--stroke); }

.section-lede {
  color: var(--text-2);
  max-width: 44em;
  margin: 0 auto 36px;
}

.shot-wide {
  width: 100%;
  max-width: 760px;
  height: auto;
  border-radius: 12px;
}

.shot-wide.narrow { max-width: 330px; }

/* ── FAQ ─────────────────────────────────────────────────────────────────── */

.faq { max-width: 760px; margin: 0 auto; }
.faq h2 { text-align: center; margin-bottom: 36px; }

.faq details {
  background: var(--card);
  border: 1px solid var(--stroke);
  border-radius: 12px;
  padding: 4px 22px;
  margin-bottom: 10px;
}

.faq summary {
  cursor: pointer;
  padding: 16px 0;
  font-weight: 600;
  list-style: none;
  display: flex;
  justify-content: space-between;
  gap: 16px;
}
.faq summary::-webkit-details-marker { display: none; }

.faq summary::after {
  content: "+";
  color: var(--text-3);
  font-weight: 400;
  font-size: 1.25rem;
  line-height: 1;
}
.faq details[open] summary::after { content: "−"; }

.faq details p {
  color: var(--text-2);
  font-size: .95rem;
  margin: 0 0 16px;
}

/* ── Support ─────────────────────────────────────────────────────────────── */

.support {
  text-align: center;
  border-top: 1px solid var(--stroke);
}
.support p { color: var(--text-2); max-width: 40em; margin: 0 auto 28px; }

/*
  Buy Me a Coffee's official button, rebuilt in CSS on purpose.

  Their generated embed is a <script> from cdnjs.buymeacoffee.com that injects the button
  and pulls the "Cookie" webfont. Three reasons this is a plain <a> styled to match
  instead:

    - It cannot fail. Widget scripts like this are a standard ad-blocker target, and when
      the script is blocked the button does not degrade — it is absent. A link is always
      there.
    - No layout shift. A script-injected button appears after first paint and pushes
      content down, which is exactly what Cumulative Layout Shift measures and penalises.
    - No third party on the page. The privacy page can keep saying what it says, and a
      visitor who came here nervous about an unsigned installer is not asked to also load
      code from a payments company.

  #FFDD00 on black is their brand yellow from the generated snippet, so it still reads as
  the button people recognise.
*/
.coffee-big {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  background: #FFDD00;
  color: #000;
  font-weight: 700;
  font-size: 1.05rem;
  letter-spacing: .01em;
  padding: 13px 26px;
  border-radius: 10px;
  box-shadow: 0 2px 0 rgba(0,0,0,.45);
}
.coffee-big:hover {
  text-decoration: none;
  filter: brightness(1.05);
  transform: translateY(-1px);
}
.coffee-big:active { transform: translateY(1px); box-shadow: 0 1px 0 rgba(0,0,0,.45); }

/* ── Ads ─────────────────────────────────────────────────────────────────── */

/*
  Labelled, boxed and given a fixed minimum height on purpose.

  Labelled because an unlabelled ad on a page offering a download is indistinguishable
  from the download — that is exactly how people end up installing the wrong thing, and
  a site that does it to them does not deserve the install.

  Fixed height because an ad script that loads late otherwise shoves the page down under
  whatever the reader was about to click.
*/
.ad-slot {
  margin: 8px 0 24px;
  text-align: center;
}

.ad-label {
  display: block;
  font-size: .68rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--text-3);
  margin-bottom: 8px;
}

.ad-box {
  min-height: 110px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--card);
  border: 1px dashed var(--stroke);
  border-radius: 12px;
  overflow: hidden;
}

.ad-placeholder { color: var(--text-3); font-size: .85rem; }

/* ── Footer ──────────────────────────────────────────────────────────────── */

footer {
  border-top: 1px solid var(--stroke);
  padding: 32px 24px 48px;
  text-align: center;
  color: var(--text-2);
  font-size: .9rem;
}
footer a { color: var(--text-2); }
footer a:hover { color: var(--text); }
footer .small { color: var(--text-3); font-size: .82rem; margin: 6px 0 0; }

/* ── Narrow ──────────────────────────────────────────────────────────────── */

@media (max-width: 860px) {
  .hero {
    grid-template-columns: 1fr;
    gap: 40px;
    text-align: center;
    padding-top: 16px;
  }
  .lede { margin-left: auto; margin-right: auto; }
  .hero-shot { order: 2; }
  .hero-shot img { max-width: 290px; }
  section { padding: 56px 0; }
  .nav nav { gap: 14px; }
  .nav nav a:not(.coffee) { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .download { transition: none; }
  .download:hover { transform: none; }
}

/* ══════════════════════════════════════════════════════════════════════════
   Guides
   ══════════════════════════════════════════════════════════════════════════ */

.guide {
  max-width: 760px;
  margin: 0 auto;
  padding: 48px 0 80px;
}

.guide h1 { font-size: clamp(1.8rem, 4vw, 2.5rem); margin-bottom: .3em; }
.guide h2 { font-size: 1.3rem; margin: 2.4em 0 .6em; }
.guide h3 { font-size: 1.02rem; margin: 1.8em 0 .5em; }

.guide p, .guide li { color: var(--text-2); }
.guide strong { color: var(--text); font-weight: 600; }

.guide ul, .guide ol { padding-left: 1.3em; margin: 0 0 1em; }
.guide li { margin-bottom: .45em; }

/* The one-line answer, before any of the explanation. Someone who arrived from a search
   result wants the instruction, not the reasoning — the reasoning is why they stay. */
.answer {
  background: var(--card);
  border: 1px solid var(--stroke);
  border-left: 3px solid var(--accent);
  border-radius: 10px;
  padding: 16px 20px;
  margin: 0 0 2em;
}
.answer p { margin: 0; color: var(--text); }

/* Screenshots are captured at 2x and shown at 1x, which is what keeps them sharp on a
   phone. The width here must stay half the pixel width of the crop. */
.guide figure { margin: 1.6em 0; }

.guide figure img {
  display: block;
  width: 100%;
  max-width: 376px;
  height: auto;
  border-radius: 10px;
  border: 1px solid var(--stroke);
}

.guide figure.wide img { max-width: 580px; }

.guide figcaption {
  color: var(--text-3);
  font-size: .85rem;
  margin-top: .7em;
}

.steps { counter-reset: step; list-style: none; padding-left: 0; }

.steps li {
  counter-increment: step;
  position: relative;
  padding-left: 40px;
  margin-bottom: 1em;
}

.steps li::before {
  content: counter(step);
  position: absolute;
  left: 0;
  top: -1px;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--card-hover);
  border: 1px solid var(--stroke);
  color: var(--text);
  font-size: .82rem;
  font-weight: 650;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Something that will bite the reader if they don't know it. Amber, the same meaning the
   app gives that colour: attention, not "in effect". */
.note {
  border-left: 3px solid var(--warning);
  background: var(--card);
  border-radius: 8px;
  padding: 14px 18px;
  margin: 1.6em 0;
  font-size: .94rem;
}
.note p { margin: 0; }
.note strong { color: var(--warning); }

.crumb { font-size: .87rem; color: var(--text-3); margin-bottom: 1.5em; }
.crumb a { color: var(--text-3); }

.guide-nav {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  margin-top: 3.5em;
  padding-top: 1.5em;
  border-top: 1px solid var(--stroke);
  font-size: .92rem;
}

/* Index cards */

.guide-list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 14px;
  margin-top: 2em;
}

.guide-list a {
  display: block;
  background: var(--card);
  border: 1px solid var(--stroke);
  border-radius: 12px;
  padding: 20px 22px;
  color: var(--text);
}
.guide-list a:hover { background: var(--card-hover); text-decoration: none; }
.guide-list h3 { margin: 0 0 .35em; font-size: 1rem; }
.guide-list p { margin: 0; color: var(--text-2); font-size: .9rem; }

/* ── Comparison table (compare.html) ────────────────────────────────────────────
   Only used on one page, but it lives here rather than in a <style> block so the
   palette variables stay the single source of truth for colour.

   .table-wrap is what makes it survive a phone: the table itself refuses to shrink
   below a readable width and the wrapper scrolls horizontally instead of letting the
   columns collapse into unreadable slivers. */
.table-wrap {
  overflow-x: auto;
  margin: 1.5rem 0 .75rem;
  border: 1px solid var(--stroke);
  border-radius: var(--radius);
}

table.compare {
  width: 100%;
  min-width: 34rem;
  border-collapse: collapse;
  font-size: .93rem;
}

table.compare th,
table.compare td {
  padding: .7rem .85rem;
  text-align: left;
  border-bottom: 1px solid var(--stroke);
  vertical-align: top;
}

table.compare thead th {
  background: var(--card);
  color: var(--text);
  font-weight: 600;
  white-space: nowrap;
  position: sticky;
  top: 0;
}

/* Row headers are the feature names. They carry the most text, so they get the room. */
table.compare tbody th {
  color: var(--text-2);
  font-weight: 400;
  width: 38%;
}

table.compare tbody tr:last-child th,
table.compare tbody tr:last-child td { border-bottom: none; }

table.compare tbody tr:hover { background: var(--card); }

/* Yes/no are carried by the words, not the colour — the cells say "Yes" and "No"
   rather than using a tick and a cross, so the table still reads correctly for anyone
   who cannot distinguish the two hues, and reads at all in a screen reader. */
table.compare td.y { color: var(--text); }
table.compare td.n { color: var(--text-3); }
