/* tubeless.app: the one stylesheet

   1. Font
   2. Colours, type and space
   3. Reset
   4. Base elements
   5. Header and footer
   6. The opening
   7. Hand-drawn bits: notes, tags and the stamp
   8. Before and after
   9. Sections
  10. What it can hide, with the popup beside it
  11. Where it works
  12. The Safari card
  13. Motion and print

   Colours come from the extension's popup, so the site and the popup
   match. Every colour has a light and a dark value; the reader's own
   setting chooses, and data-theme="light" or "dark" on <html> forces
   one. */


/* 1. Font

   Geist, the popup's typeface, copied from the extension build. Without
   the file, the page falls back to the system sans. */

@font-face {
  font-family: "Geist";
  src: url("fonts/geist-latin-wght-normal.1e9a91c7.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}


/* 2. Colours, type and space */

:root {
  color-scheme: light dark;

  --paper: #f4ede0;
  --surface: #fcf8ef;
  --well: #ece2ce;      /* the popup's segmented control background */
  --ink: #1c1812;
  --quiet: #6e634f;
  --rule: #cfc2a4;
  --accent: #dc4f2a;    /* the logo's pill, link underlines, focus rings */
  --button: #c4421f;    /* the accent, a touch deeper, so white text passes 4.5:1 */
  --on-button: #ffffff;
  --switch-off: #d4c8b1; /* the popup's switch track when off */
  --thumb: #ffffff;
  --shadow: #ddd0b4;    /* the flat offset shadow under screenshots */

  --display: "Iowan Old Style", "Sitka Text", Charter, Georgia, serif;
  --body: "Geist", system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;

  --small: clamp(0.9rem, 0.88rem + 0.1vw, 0.98rem);
  --text: clamp(1.06rem, 1rem + 0.3vw, 1.19rem);
  --lede: clamp(1.2rem, 1.1rem + 0.45vw, 1.42rem);
  --heading: clamp(1.6rem, 1.4rem + 1vw, 2.2rem);
  --title: clamp(2.7rem, 1.8rem + 3.6vw, 4.5rem);

  --gutter: clamp(1rem, 4vw, 2rem);
  --column: 40rem;
  --wide: 62rem;
  --corner: 8px;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --paper: #191919;
    --surface: #20201f;
    --well: #2a2929;
    --ink: #e7e6e5;
    --quiet: #929190;
    --rule: #3e3d3c;
    --accent: #f26b45;
    --button: #f26b45;
    --on-button: #191919;
    --switch-off: #454444;
    --thumb: #e7e6e5;
    --shadow: #2c2b2a;
  }
}

:root[data-theme="light"] {
  color-scheme: light;
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --paper: #191919;
  --surface: #20201f;
  --well: #2a2929;
  --ink: #e7e6e5;
  --quiet: #929190;
  --rule: #3e3d3c;
  --accent: #f26b45;
  --button: #f26b45;
  --on-button: #191919;
  --switch-off: #454444;
  --thumb: #e7e6e5;
  --shadow: #2c2b2a;
}

@media (prefers-contrast: more) {
  :root {
    --quiet: var(--ink);
    --rule: color-mix(in oklab, var(--ink) 55%, var(--paper));
  }
}


/* 3. Reset */

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

* {
  margin: 0;
}

img,
svg {
  display: block;
  max-inline-size: 100%;
  block-size: auto;
}

fieldset {
  border: 0;
  padding: 0;
  min-inline-size: 0;
}

.visually-hidden {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}


/* 4. Base elements */

body {
  background: var(--paper);
  color: var(--ink);
  font-family: var(--body);
  font-size: var(--text);
  line-height: 1.65;
  overflow-wrap: break-word;
  -webkit-text-size-adjust: 100%;
}

h1,
h2 {
  font-family: var(--display);
  font-weight: 600;
  line-height: 1.2;
  text-wrap: balance;
}

h3 {
  font-size: 1em;
  font-weight: 650;
  line-height: 1.35;
  text-wrap: balance;
}

p,
li,
dd,
td {
  text-wrap: pretty;
}

/* Links are the colour of the text and always underlined, so none is
   told apart by colour alone. The underline is the accent, and thickens
   under the pointer. */
a {
  color: inherit;
  text-decoration-line: underline;
  text-decoration-color: var(--accent);
  text-decoration-thickness: max(1.5px, 0.1em);
  text-underline-offset: 0.22em;
  transition: text-decoration-thickness 0.15s ease;
}

a:hover {
  text-decoration-thickness: 0.32em;
}

:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 3px;
  border-radius: 4px;
}

code {
  font-family: var(--mono);
  font-size: 0.86em;
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: 5px;
  padding: 0.05em 0.35em;
}

.skip {
  position: absolute;
  inset-block-start: -5rem;
  inset-inline-start: 1rem;
  z-index: 5;
  padding: 10px 16px;
  background: var(--button);
  color: var(--on-button);
  border-radius: var(--corner);
  font-weight: 650;
  text-decoration: none;
}

.skip:focus {
  inset-block-start: 0.75rem;
}

/* Jumping to a section from the menu leaves a little room above it. */
[id] {
  scroll-margin-block-start: 24px;
}


/* 5. Header and footer */

.site-header {
  max-inline-size: var(--wide);
  margin-inline: auto;
  padding: 18px var(--gutter);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 4px 24px;
}

.brand {
  display: inline-flex;
  align-items: center;
  min-block-size: 44px;
  text-decoration: none;
}

.brand svg {
  inline-size: 170px;
  block-size: auto;
}

.brand .pill {
  fill: none;
  stroke: var(--accent);
}

.brand .word {
  fill: var(--ink);
}

.site-header ul {
  list-style: none;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0 20px;
}

.site-header nav a {
  display: inline-block;
  padding-block: 10px;
  font-size: var(--small);
  text-decoration-color: transparent;
}

.site-header nav a:hover {
  text-decoration-color: var(--accent);
}

.site-footer {
  max-inline-size: var(--column);
  margin-inline: auto;
  padding: 96px var(--gutter) 48px;
}

.site-footer div {
  padding-block-start: 24px;
  border-block-start: 1px solid var(--rule);
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: var(--small);
  color: var(--quiet);
}

.site-footer p:first-child {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 10px;
}

.site-footer .pill {
  flex: none;
  fill: none;
  stroke: var(--accent);
}


/* 6. The opening */

.hero {
  max-inline-size: var(--column);
  margin-inline: auto;
  padding: 64px var(--gutter) 48px;
}

.hero h1 {
  margin-block-end: 22px;
  font-size: var(--title);
  line-height: 1.04;
  letter-spacing: -0.015em;
}

.lede {
  font-size: var(--lede);
  line-height: 1.55;
}

.actions {
  container-type: inline-size;
  margin-block-start: 30px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 14px;
}

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-block-size: 48px;
  padding: 0 22px;
  border: 2px solid var(--ink);
  border-radius: var(--corner);
  font-weight: 650;
  text-decoration: none;
  transition: transform 0.15s ease;
}

.button:hover {
  transform: translateY(-1px);
}

.button-main {
  background: var(--button);
  border-color: var(--button);
  color: var(--on-button);
}

.actions .button {
  padding-inline: 18px;
}

/* Below this width the note wraps under the buttons, so the arrow turns
   to point up at them. 34rem is just over the row's width on one line with
   two buttons; with three, the note never fits beside them. */
@container (width < 34rem) {
  .actions .scribble {
    padding-inline-start: 12px;
  }

  .actions .scribble svg {
    transform: rotate(35deg);
  }
}

.actions:has(> .button:nth-of-type(3)) .scribble {
  padding-inline-start: 12px;
}

.actions:has(> .button:nth-of-type(3)) .scribble svg {
  transform: rotate(35deg);
}

.hero-note {
  margin-block-start: 26px;
  font-size: var(--small);
}

.hero-note + .hero-note {
  margin-block-start: 10px;
}

.hero-note .tag {
  margin-inline-end: 6px;
}

.meta {
  margin-block-start: 10px;
  font-size: var(--small);
  color: var(--quiet);
}

@media (max-width: 30rem) {
  .actions .button {
    flex: 1 1 100%;
  }
}


/* 7. Hand-drawn bits: notes, tags and the stamp */

/* A note in the margin, as if written in pencil. */
.scribble {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding-inline-start: 4px;
  font-family: var(--display);
  font-style: italic;
  font-size: 1.1rem;
  line-height: 1.3;
  color: var(--quiet);
  transform: rotate(-3deg);
}

.scribble svg {
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* A word ringed in the accent, like a label stuck on. */
.tag {
  display: inline-block;
  padding: 0 7px;
  border: 1.5px solid var(--accent);
  border-radius: 999px;
  font-size: 0.78em;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  line-height: 1.6;
  transform: rotate(-4deg);
}

/* An ink stamp, a bit squint, on a section heading. */
.stamp {
  display: inline-block;
  margin-inline-start: 10px;
  padding: 1px 8px 0;
  border: 2px solid var(--accent);
  border-radius: 4px;
  color: var(--accent);
  font-family: var(--body);
  font-size: 0.42em;
  font-weight: 750;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  vertical-align: 0.45em;
  transform: rotate(-7deg);
}


/* 8. Before and after

   Four screenshots in one frame. The radio buttons pick the page and the
   switch turns Tubeless on; :has() shows the screenshot that matches.
   All four sit in the same grid cell, so they load together and the
   frame never changes height. */

.shots {
  max-inline-size: var(--wide);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.shots-controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 14px 24px;
  margin-block-end: 16px;
}

/* The popup's segmented control, made of radio buttons. */
.segmented {
  display: inline-flex;
  padding: 3px;
  background: var(--well);
  border-radius: 10px;
}

.segmented label {
  position: relative;
  padding: 6px 14px;
  border-radius: 7px;
  font-size: var(--small);
  font-weight: 600;
  color: var(--quiet);
  cursor: pointer;
}

.segmented input {
  position: absolute;
  inset: 0;
  opacity: 0;
  cursor: pointer;
}

.segmented label:has(:checked) {
  background: var(--surface);
  color: var(--ink);
  box-shadow: 0 1px 2px rgb(0 0 0 / 0.12);
}

.segmented label:has(:focus-visible) {
  outline: 3px solid var(--accent);
  outline-offset: 2px;
}

.shots-power {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 16px;
}

/* The popup's switch, at a size a thumb can hit. */
.switch {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-block-size: 44px;
  font-weight: 650;
  cursor: pointer;
}

.switch input {
  position: absolute;
  inset: 0;
  opacity: 0;
  cursor: pointer;
}

.switch-track {
  flex: none;
  position: relative;
  inline-size: 46px;
  block-size: 26px;
  border-radius: 13px;
  background: var(--switch-off);
  transition: background-color 0.2s ease;
}

.switch-thumb {
  position: absolute;
  inset-block-start: 3px;
  inset-inline-start: 3px;
  inline-size: 20px;
  block-size: 20px;
  border-radius: 50%;
  background: var(--thumb);
  box-shadow: 0 1px 2px rgb(0 0 0 / 0.3);
  transition: transform 0.2s ease;
}

.switch:has(:checked) .switch-track {
  background: var(--accent);
}

.switch:has(:checked) .switch-thumb {
  transform: translateX(20px);
}

.switch:has(:focus-visible) .switch-track {
  outline: 3px solid var(--accent);
  outline-offset: 3px;
}

.switch-state {
  font-weight: 400;
  color: var(--quiet);
}

/* Words that change with the switch. */
.shots .when-on {
  display: none;
}

.shots:has(.shots-on:checked) .when-on {
  display: inline;
}

.shots:has(.shots-on:checked) .when-off {
  display: none;
}

.scribble-flip {
  transform: rotate(-2deg);
}

.scribble-flip svg {
  transform: translateY(-3px);
}

.shots-frame {
  display: grid;
  gap: 20px;
}

.shot img {
  inline-size: 100%;
  border: 1.5px solid var(--rule);
  border-radius: 10px;
  box-shadow: 5px 6px 0 var(--shadow);
  background: #1c1b1f;
}

.shots figcaption {
  max-inline-size: var(--column);
  margin-block-start: 18px;
  font-size: var(--small);
  color: var(--quiet);
}

@supports selector(:has(*)) {
  .shots-frame {
    gap: 0;
  }

  .shot {
    grid-area: 1 / 1;
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.25s ease, visibility 0s linear 0.25s;
  }

  .shots:has(.shots-home:checked):not(:has(.shots-on:checked)) .shot-home.shot-off,
  .shots:has(.shots-home:checked):has(.shots-on:checked) .shot-home.shot-on,
  .shots:has(.shots-watch:checked):not(:has(.shots-on:checked)) .shot-watch.shot-off,
  .shots:has(.shots-watch:checked):has(.shots-on:checked) .shot-watch.shot-on {
    opacity: 1;
    visibility: visible;
    transition: opacity 0.25s ease;
  }
}

/* Without :has() the controls can't do anything, so they go. */
@supports not selector(:has(*)) {
  .shots-controls {
    display: none;
  }
}


/* 9. Sections */

.section {
  max-inline-size: var(--column);
  margin-inline: auto;
  padding: 88px var(--gutter) 0;
}

.section h2 {
  margin-block-end: 14px;
  font-size: var(--heading);
}

.section h3 {
  margin-block: 32px 6px;
}

.section h2 + h3 {
  margin-block-start: 20px;
}

.section p + p,
.section ul + p,
.section ol + p,
.section table + p,
.section dl + p {
  margin-block-start: 16px;
}

.section > p:has(+ dl),
.section > p:has(+ pre),
.section > p:has(+ ul),
.section > p:has(+ ol),
.section > p:has(+ table) {
  margin-block-end: 18px;
}

.section ul,
.section ol {
  padding-inline-start: 1.4em;
}

.section li + li {
  margin-block-start: 8px;
}

.section ul li::marker {
  content: "–  ";
  color: var(--accent);
}

.section ol li::marker {
  font-family: var(--display);
  font-weight: 600;
  color: var(--accent);
}

.section dl {
  display: grid;
  grid-template-columns: minmax(0, 8.5rem) minmax(0, 1fr);
  border-block-start: 1px solid var(--rule);
}

.section dl dt,
.section dl dd {
  padding-block: 14px;
  border-block-end: 1px solid var(--rule);
}

.section dl dt {
  padding-inline-end: 20px;
  font-weight: 650;
}

@media (max-width: 30rem) {
  .section dl {
    grid-template-columns: minmax(0, 1fr);
  }

  .section dl dt {
    padding-block-end: 0;
    border-block-end: 0;
  }

  .section dl dd {
    padding-block-start: 2px;
  }
}

pre {
  margin-block-end: 22px;
  padding: 18px 22px;
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: var(--corner);
  font-family: var(--mono);
  font-size: 0.9rem;
  line-height: 1.7;
  overflow-x: auto;
}

pre code {
  background: none;
  border: 0;
  padding: 0;
  font-size: inherit;
}

pre .muted {
  color: var(--quiet);
}

/* The questions read as a list of their own, each answer under its
   question in a quieter run. */
#questions h3 {
  font-family: var(--display);
  font-size: 1.2em;
  font-weight: 600;
}

/* The release notes: version and date as small headings. */
#new h3 {
  font-size: var(--small);
  letter-spacing: 0.02em;
}

#new h3 + ul {
  font-size: var(--small);
}

.signature {
  font-family: var(--display);
  font-style: italic;
  font-size: 1.35rem;
}


/* 10. What it can hide, with the popup beside it

   On a wide screen the popup sits to the right of the writing and stays
   in view while you read down the list. On a narrow one it comes after
   the opening paragraphs. Either way it's in a box the height of the
   real popup, and scrolls the same way. */

.section-wide {
  max-inline-size: var(--wide);
}

.popup-shot {
  margin-block: 28px;
}

.popup-scroll {
  max-inline-size: 320px;
  block-size: min(560px, 70vh);
  margin-inline: auto;
  overflow-y: auto;
  border: 1.5px solid var(--rule);
  border-radius: 12px;
  background: var(--paper);
  box-shadow: 5px 6px 0 var(--shadow);
  scrollbar-width: thin;
  scrollbar-color: var(--rule) transparent;
}

.popup-scroll img {
  inline-size: 100%;
}

.popup-shot figcaption {
  max-inline-size: 320px;
  margin: 16px auto 0;
  font-family: var(--display);
  font-style: italic;
  font-size: 1.05rem;
  line-height: 1.4;
  color: var(--quiet);
  transform: rotate(-1.5deg);
}

@media (min-width: 56rem) {
  .section-wide {
    display: grid;
    grid-template-columns: minmax(0, var(--column)) 320px;
    justify-content: space-between;
    column-gap: 48px;
    align-items: start;
  }

  .section-wide > * {
    grid-column: 1;
  }

  .section-wide > p:has(+ .popup-shot) {
    margin-block-end: 18px;
  }

  .section-wide > .popup-shot {
    grid-column: 2;
    grid-row: 1 / span 20;
    position: sticky;
    inset-block-start: 24px;
    margin-block: 6px 0;
  }

  .popup-scroll {
    block-size: min(600px, calc(100vh - 140px));
  }
}


/* 11. Where it works

   A plain ruled table. Each answer starts with a word in bold and a
   mark before it, so it reads the same without colour. */

.section table {
  inline-size: 100%;
  border-collapse: collapse;
  font-size: var(--small);
  line-height: 1.5;
}

.section th,
.section td {
  padding: 12px 14px 12px 0;
  border-block-end: 1px solid var(--rule);
  text-align: start;
  vertical-align: top;
}

.section th {
  border-block-end-width: 2px;
  border-block-end-color: var(--ink);
  font-weight: 650;
}

.section td:first-child {
  font-weight: 600;
}

.section td:nth-child(2) {
  white-space: nowrap;
}

.section table + p {
  margin-block-start: 20px;
}

.works,
.maybe,
.soon,
.nope {
  font-weight: 650;
  white-space: nowrap;
}

.works::before { content: "✓ "; color: var(--accent); }
.maybe::before { content: "≈ "; color: var(--accent); }
.soon::before  { content: "→ "; color: var(--accent); }
.nope::before  { content: "✗ "; color: var(--quiet); }

/* On a phone, each row becomes a short stack: the browser, then where
   to get it, then the answer. */
@media (max-width: 34rem) {
  .section thead {
    position: absolute;
    inline-size: 1px;
    block-size: 1px;
    overflow: hidden;
    clip-path: inset(50%);
  }

  .section table,
  .section tbody,
  .section tr,
  .section td {
    display: block;
  }

  .section tr {
    padding-block: 12px;
    border-block-end: 1px solid var(--rule);
  }

  .section tbody tr:first-child {
    border-block-start: 2px solid var(--ink);
  }

  .section td {
    padding: 0;
    border: 0;
  }

  .section td + td {
    margin-block-start: 2px;
  }

  /* The headings are hidden here, so name each value. Screen readers
     still get the headings, so the label is left out for them. */
  .section td[data-label]::before {
    content: attr(data-label) ": " / "";
    color: var(--quiet);
  }
}


/* 12. The Safari card

   The one section drawn as a card, with a dashed edge and a stamp on the
   heading. The card is painted behind the section, so the writing inside
   lines up with every other section. On a narrow screen the writing steps
   in to make room for it instead. */

.section-card {
  position: relative;
  isolation: isolate;
  margin-block-start: 88px;
  padding-block: 30px 32px;
}

.section-card::before {
  content: "";
  position: absolute;
  z-index: -1;
  inset-block: 0;
  inset-inline: -14px;
  background: var(--surface);
  border: 1.5px dashed var(--accent);
  border-radius: 14px;
  box-shadow: 5px 6px 0 var(--shadow);
}

@media (max-width: 46rem) {
  .section-card {
    padding-inline: calc(var(--gutter) + 18px);
  }

  .section-card::before {
    inset-inline: var(--gutter);
  }
}

/* A crown stuck on the card's top corner, like a sticker. */
.section-card > .corner {
  position: absolute;
  inset-block-start: -22px;
  inset-inline-end: -30px;
  display: grid;
  place-items: center;
  inline-size: 52px;
  block-size: 52px;
  background: var(--surface);
  border: 1.5px solid var(--accent);
  border-radius: 50%;
  box-shadow: 3px 4px 0 var(--shadow);
  color: var(--accent);
  transform: rotate(12deg);
}

.section-card > .corner svg {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

@media (max-width: 46rem) {
  .section-card > .corner {
    inset-inline-end: calc(var(--gutter) - 8px);
  }
}

.section-card > :last-child {
  margin-block-end: 0;
}

.safari-join {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 16px;
  margin-block: 22px 26px;
}

.safari-status {
  margin-block: 22px 26px;
  padding-inline-start: 14px;
  border-inline-start: 3px solid var(--accent);
}

.safari-join-note {
  font-size: var(--small);
  color: var(--quiet);
}

@media (max-width: 30rem) {
  .safari-join .button {
    flex: 1 1 100%;
  }
}


/* 13. Motion and print */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    transition: none !important;
  }

  .button:hover {
    transform: none;
  }
}

@media print {
  .skip,
  .site-header nav,
  .actions,
  .shots-controls,
  .safari-join {
    display: none;
  }

  a {
    text-decoration: none;
  }

  .popup-scroll {
    block-size: auto;
    overflow: visible;
  }
}
