/* LinuxStreamDeck — presentation and manual.
   Dark by default because the application is, and because every key picture
   on this page is composed on a dark background: a light page would put them
   in boxes. A light theme follows the visitor's own setting. */

:root {
  color-scheme: dark;
  --bg: #0e0f13;
  --bg-soft: #15161c;
  --bg-card: #181a21;
  --line: #262933;
  --ink: #e7e9ee;
  --ink-dim: #a0a6b4;
  --ink-faint: #6f7684;
  --accent: #4a9eff;
  --accent-soft: rgba(74, 158, 255, 0.12);
  --live: #26a269;
  --rec: #e0405a;
  --warn: #e0a03a;
  --header-h: 64px;
  --radius: 14px;
  --shadow: 0 18px 50px rgba(0, 0, 0, 0.45);
  --mono: ui-monospace, "JetBrains Mono", "Fira Code", Menlo, Consolas, monospace;
  --sans: system-ui, -apple-system, "Segoe UI", Inter, "Cantarell", sans-serif;
}

@media (prefers-color-scheme: light) {
  :root {
    color-scheme: light;
    --bg: #f7f8fa;
    --bg-soft: #ffffff;
    --bg-card: #ffffff;
    --line: #e0e3ea;
    --ink: #14161c;
    --ink-dim: #4d5563;
    --ink-faint: #79808f;
    --accent: #0b6bd6;
    --accent-soft: rgba(11, 107, 214, 0.09);
    --shadow: 0 14px 40px rgba(19, 24, 38, 0.10);
    /* The dark theme's amber is only 2:1 on white, and it is what the
       "needs OBS" chip is drawn in. This one measures 4.9:1. */
    --warn: #9a6608;
  }
}

* { box-sizing: border-box; }

/* Grid and flex children default to `min-width: auto`, which is the widest
   thing inside them that cannot be broken. One <pre> holding
   "sudo apt install ./linux-stream-deck-X.Y.Z.deb" measured 542 px inside a
   453 px column, so the column refused to shrink and the whole page scrolled
   sideways on every phone. `overflow-x: auto` on the <pre> does not help:
   the minimum is decided by the grid item above it. */
.guide > *, .feature > *, .card, .hero, footer .wrap { min-width: 0; }

/* A path, a URL or a command has no spaces to break at, so a long one sets
   that same unbreakable minimum from inside a paragraph. Inline code may
   break anywhere; a block of code keeps its lines intact and scrolls, which
   is what `pre` already does. */
code { overflow-wrap: anywhere; }
pre code { overflow-wrap: normal; }

html { scroll-behavior: smooth; scroll-padding-top: calc(var(--header-h) + 20px); }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

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

code, kbd {
  font-family: var(--mono);
  font-size: 0.88em;
  background: var(--accent-soft);
  color: var(--ink);
  padding: 0.12em 0.42em;
  border-radius: 5px;
}

pre {
  background: var(--bg-soft);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 14px 16px;
  overflow-x: auto;
}
pre code { background: none; padding: 0; font-size: 0.85rem; line-height: 1.55; }

.wrap { width: min(1120px, calc(100% - 48px)); margin-inline: auto; }

/* ---------------------------------------------------------------- header */

header.top {
  position: sticky;
  top: 0;
  z-index: 50;
  backdrop-filter: blur(14px);
  background: color-mix(in srgb, var(--bg) 86%, transparent);
  border-bottom: 1px solid var(--line);
}
.top .wrap {
  display: flex;
  align-items: center;
  gap: 22px;
  /* min-height, not height: if the nav ever does wrap - a longer link, a
     visitor with a larger minimum font - the bar grows and pushes the page
     down instead of drawing the links on top of it. */
  min-height: var(--header-h);
}
.brand { display: flex; align-items: center; gap: 10px; font-weight: 650; letter-spacing: -0.01em; }
.brand img { width: 26px; height: 26px; }
.brand span { color: var(--ink); }
/* align-items is needed, not optional. The default stretch makes every link as
   tall as the padded GitHub button, and a link with no padding of its own then
   draws its text at the top of that stretched box — 8 px above the button and
   the brand, both of which sit correctly on the header's centre line. It reads
   as the button hanging low; it is the links riding high. */
.top nav { display: flex; align-items: center; gap: 20px; margin-left: auto; flex-wrap: wrap; }
.top nav a { color: var(--ink-dim); font-size: 0.92rem; font-weight: 500; }
.top nav a:hover { color: var(--ink); text-decoration: none; }
.ghost {
  border: 1px solid var(--line);
  border-radius: 9px;
  padding: 7px 14px;
  color: var(--ink) !important;
  font-size: 0.9rem;
}
.ghost:hover { border-color: var(--accent); }

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

.hero { padding: 78px 0 64px; text-align: center; }
.hero .badge {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  border: 1px solid var(--line);
  background: var(--bg-soft);
  color: var(--ink-dim);
  border-radius: 999px;
  padding: 6px 14px;
  font-size: 0.82rem;
  margin-bottom: 22px;
}
.hero .badge b { color: var(--accent); font-weight: 600; }
.hero h1 {
  font-size: clamp(2.1rem, 5.4vw, 3.5rem);
  line-height: 1.08;
  letter-spacing: -0.032em;
  margin: 0 0 18px;
  font-weight: 700;
}
.hero h1 em { font-style: normal; color: var(--accent); }
.hero p.lead {
  font-size: clamp(1.02rem, 2vw, 1.2rem);
  color: var(--ink-dim);
  max-width: 660px;
  margin: 0 auto 30px;
}
.cta { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; }
.btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  border-radius: 10px;
  padding: 11px 20px;
  font-weight: 600;
  font-size: 0.95rem;
  border: 1px solid transparent;
}
.btn.primary { background: var(--accent); color: #fff; }
.btn.primary:hover { filter: brightness(1.1); text-decoration: none; }
.btn.plain { border-color: var(--line); color: var(--ink); background: var(--bg-soft); }
.btn.plain:hover { border-color: var(--accent); text-decoration: none; }

.shot {
  margin: 54px auto 0;
  max-width: 980px;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  box-shadow: var(--shadow);
  overflow: hidden;
  background: var(--bg-soft);
}
.shot img { display: block; width: 100%; height: auto; }

/* --------------------------------------------------------------- section */

section { padding: 68px 0; border-top: 1px solid var(--line); }
section > .wrap > h2 {
  font-size: clamp(1.5rem, 3vw, 2rem);
  letter-spacing: -0.022em;
  margin: 0 0 10px;
  font-weight: 680;
}
section > .wrap > p.sub {
  color: var(--ink-dim);
  max-width: 720px;
  margin: 0 0 36px;
  font-size: 1.02rem;
}
h3 { font-size: 1.12rem; margin: 0 0 8px; font-weight: 640; letter-spacing: -0.01em; }

/* ------------------------------------------------------------ why / diff */

/* minmax is 320 rather than 258 so six cards land as 3 + 3 at full width
   instead of 4 + 2, which reads as two of them having been left over. */
.diff { display: grid; gap: 18px;
  grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr)); }
.diff article {
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 22px 22px 24px;
}
.diff .mark {
  width: 34px; height: 34px;
  display: grid; place-items: center;
  border-radius: 9px;
  background: var(--accent-soft);
  color: var(--accent);
  font-size: 1.05rem;
  margin-bottom: 14px;
}
.diff p { margin: 0; color: var(--ink-dim); font-size: 0.95rem; }

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

.feature {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 46px;
  align-items: center;
  padding: 34px 0;
}
.feature:nth-child(even) .text { order: 2; }
.feature .text h3 { font-size: 1.34rem; margin-bottom: 12px; }
.feature .text p { color: var(--ink-dim); margin: 0 0 12px; }
.feature figure { margin: 0; }
.feature figure img { width: 100%; height: auto; display: block; }
.feature figcaption {
  margin-top: 10px;
  color: var(--ink-faint);
  font-size: 0.82rem;
  text-align: center;
}
.tagrow { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 14px; }
.tag {
  font-size: 0.78rem;
  color: var(--ink-dim);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 3px 10px;
  background: var(--bg-soft);
}

/* ------------------------------------------------------------- explorer */

.finder { position: sticky; top: var(--header-h); z-index: 20; padding: 16px 0 18px; background: var(--bg); }
.searchbox { position: relative; }
.searchbox input {
  width: 100%;
  background: var(--bg-soft);
  border: 1px solid var(--line);
  border-radius: 11px;
  color: var(--ink);
  font: inherit;
  font-size: 1rem;
  padding: 13px 16px 13px 44px;
}
.searchbox input:focus { outline: 2px solid var(--accent); outline-offset: 1px; border-color: transparent; }
.searchbox svg { position: absolute; left: 14px; top: 50%; transform: translateY(-50%); color: var(--ink-faint); }
.filters { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.filters button {
  font: inherit;
  font-size: 0.85rem;
  cursor: pointer;
  border: 1px solid var(--line);
  background: var(--bg-soft);
  color: var(--ink-dim);
  border-radius: 999px;
  padding: 5px 13px;
}
.filters button:hover { color: var(--ink); }
.filters button[aria-pressed="true"] {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}
.count { color: var(--ink-faint); font-size: 0.86rem; margin: 14px 0 4px; }

/* min() matters here: below a 320 px viewport a bare minmax(320px, 1fr)
   track is wider than the page and everything scrolls sideways. */
.cards { display: grid; gap: 14px;
  grid-template-columns: repeat(auto-fill, minmax(min(320px, 100%), 1fr)); }
.card {
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 16px 18px 18px;
}
.card header { display: flex; align-items: baseline; gap: 10px; margin-bottom: 6px; }
.card h4 { margin: 0; font-size: 1.02rem; font-weight: 640; }
.card .cat { font-size: 0.76rem; color: var(--ink-faint); margin-left: auto; white-space: nowrap; }
.card p { margin: 0 0 12px; color: var(--ink-dim); font-size: 0.9rem; }
.card .aid { font-family: var(--mono); font-size: 0.76rem; color: var(--accent); }
.card ul { margin: 0; padding: 0; list-style: none; display: flex; flex-wrap: wrap; gap: 6px; }
.card li {
  font-size: 0.76rem;
  color: var(--ink-faint);
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 2px 8px;
}
.card li.need { color: var(--warn); border-color: color-mix(in srgb, var(--warn) 40%, transparent); }
.card li.hit { color: var(--ink); border-color: color-mix(in srgb, var(--accent) 45%, transparent); }
.card mark { background: var(--accent-soft); color: var(--ink); border-radius: 3px; padding: 0 2px; }
.empty { color: var(--ink-faint); padding: 40px 0; text-align: center; }
.linkish {
  font: inherit;
  color: var(--accent);
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  text-decoration: underline;
}

/* ----------------------------------------------------------------- guide */

.guide { display: grid; grid-template-columns: 232px 1fr; gap: 48px; align-items: start; }
.guide aside { position: sticky; top: calc(var(--header-h) + 22px); }
.guide aside ol { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }
.guide aside a {
  display: block;
  color: var(--ink-dim);
  font-size: 0.9rem;
  padding: 6px 12px;
  border-radius: 8px;
  border-left: 2px solid transparent;
}
.guide aside a:hover { color: var(--ink); background: var(--bg-soft); text-decoration: none; }
.guide aside a.on { color: var(--accent); border-left-color: var(--accent); background: var(--accent-soft); }
.step { padding-bottom: 34px; }
.step h3 { display: flex; align-items: center; gap: 11px; }
.step h3 .n {
  flex: none;
  width: 25px; height: 25px;
  display: grid; place-items: center;
  border-radius: 7px;
  background: var(--accent-soft);
  color: var(--accent);
  font-size: 0.8rem;
  font-weight: 700;
}
.step p, .step ul { color: var(--ink-dim); }
.step ul { padding-left: 20px; }
.step li { margin: 5px 0; }
.note {
  border-left: 3px solid var(--accent);
  background: var(--accent-soft);
  border-radius: 0 9px 9px 0;
  padding: 12px 16px;
  margin: 16px 0;
  font-size: 0.93rem;
  color: var(--ink-dim);
}
.note b { color: var(--ink); }
/* The three-dot menu glyph. At body size in a proportional face it reads as a
   colon, so it is drawn once, as a chip the size of the button it names, and
   the guide uses words everywhere else. */
.mi {
  display: inline-grid;
  place-items: center;
  width: 1.5em;
  height: 1.5em;
  vertical-align: -0.38em;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--bg-soft);
  color: var(--ink);
  font-size: 1em;
  line-height: 1;
}

table.spec { width: 100%; border-collapse: collapse; font-size: 0.92rem; margin: 8px 0 4px; }
table.spec th, table.spec td { text-align: left; padding: 9px 12px; border-bottom: 1px solid var(--line); }
table.spec th { color: var(--ink-faint); font-weight: 600; font-size: 0.82rem; text-transform: uppercase; letter-spacing: 0.04em; }
table.spec td { color: var(--ink-dim); }
table.spec td:first-child { color: var(--ink); white-space: nowrap; }
.scroll-x { overflow-x: auto; }

footer {
  border-top: 1px solid var(--line);
  padding: 40px 0 56px;
  color: var(--ink-faint);
  font-size: 0.89rem;
}
footer .wrap { display: flex; gap: 18px; flex-wrap: wrap; align-items: center; }
footer nav { margin-left: auto; display: flex; gap: 18px; flex-wrap: wrap; }

@media (max-width: 860px) {
  .wrap { width: calc(100% - 32px); }
  .feature { grid-template-columns: 1fr; gap: 22px; padding: 26px 0; }
  .feature:nth-child(even) .text { order: 0; }
  .guide { grid-template-columns: 1fr; gap: 22px; }
  .guide aside { position: static; }
  .top nav a.hide-s { display: none; }

  /* Everything from here down is a touch device, tablets included, so every
     link has to be reachable with a thumb. Padding rather than gap, because
     gap is dead space: a bare text link is 23 px tall and a finger needs
     about 44. The header still measures 64 px, which is where the height
     comes from. */
  .top nav { gap: 4px; }
  .top nav a { padding: 11px 8px; }
  .ghost { padding: 9px 12px; }
  .brand { padding: 9px 0; }
  footer nav { gap: 4px; }
  footer nav a { padding: 10px 8px; }
  .filters button { padding: 9px 14px; }

  section { padding: 52px 0; }
  .hero { padding: 46px 0 44px; }
  .shot { margin-top: 34px; }

  /* The guide contents becomes a row of chips rather than a column, and each
     one has to be tappable: 6 px of padding is a 26 px target, under the
     44 px anyone can reliably hit. */
  .guide aside ol { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
  .guide aside a {
    border: 1px solid var(--line);
    border-left-width: 1px;
    border-radius: 999px;
    padding: 8px 14px;
    background: var(--bg-soft);
  }
  .guide aside a.on {
    border-color: var(--accent);
    border-left-color: var(--accent);
  }
}

/* One line of header, all the way down. Measured on the real page: the bar
   needs 506 px for brand plus links and a phone offers 358, so the nav wrapped
   to a second line inside a header whose height is fixed — the links were
   drawn over the page below it. The brand wordmark is 139 px of that and the
   logo still says whose site this is, so it is the thing that goes. */
@media (max-width: 620px) {
  .brand span { display: none; }
  .top .wrap { gap: 12px; }
  /* Only the sizes change here; the tap targets are already set above. */
  .top nav a { font-size: 0.88rem; }
  .ghost { font-size: 0.86rem; }

  /* Measured at 390 px: at the desktop minimum of 2.1rem the headline broke
     after "Stream", leaving "Deck," alone on a line of its own. The first
     line is 24 characters, so it needs about 28 px to fit 358 px of column -
     and the floor has to come down too, or a 320 px screen overflows. */
  .hero h1 { font-size: clamp(1.4rem, 7vw, 2.2rem); }
  .hero p.lead { font-size: 1rem; }

  .cta { flex-direction: column; align-items: stretch; }
  .cta .btn { justify-content: center; }

  /* A row of chips reads as one block of clutter when it is most of the
     screen; the pictures are what carry these sections on a phone. */
  .tagrow { display: none; }

  /* These already sit in a .scroll-x container, but `width: 100%` made them
     fit the phone instead of using it: the explanation column of the
     troubleshooting table was squeezed to five words a line. A minimum width
     lets them scroll sideways, which is what the container is for. */
  table.spec { min-width: 470px; }
  /* No scroll-shadow here on purpose. The first attempt pinned both gradients
     with `background-attachment: local`, so they scrolled away with the
     content instead of marking the box edges - it looked like an affordance
     and was not one. A row cut mid-word at the edge already says the table
     continues, and a gradient over that text would only make it harder to
     read. */


  /* The narrowest phones still in use are 320 px. Measured there, the four
     links plus the button need 312 px against 288 available, so one has to
     go, and Features is the one nobody navigates to: it is the section you
     land in by scrolling. Actions and Guide are destinations. */
  @media (max-width: 400px) {
    .top nav a.hide-xs { display: none; }
  }
  .card { padding: 14px 15px 16px; }
  /* The category is nowrap and pushed right, so beside a long action name it
     was the thing that made a card overflow. On a narrow card it belongs
     under the name. */
  .card header { display: block; }
  .card .cat { display: block; margin: 2px 0 0; }
}
