/* ============================================================
   Docket, everything that is not the landing page.

   One stylesheet behind four page types: the blog index, a post, the
   compare hub, and the two shapes of comparison page. They share a shell
   because they are the same site, and the landing page's tokens are lifted
   here unchanged so a visitor never crosses a seam.

   The anatomy is taken from what already works on Chorus and Muse: a
   masthead, a row of category tiles, a grid of cards, and for the long
   pages a single measured column with the same furniture in it every time.
   The clothes are Docket's.
   ============================================================ */

@font-face{font-family:'Plus Jakarta Sans';font-style:normal;font-weight:400 800;font-display:swap;
  src:url('../assets/fonts/plus-jakarta-sans-400800-normal-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;}

:root{
  --canvas:#FFFFFF; --sunk:#F6F6F4; --panel:#FFFFFF;
  --ink:#1F1F1E; --body:#3F3F3E; --muted:#7E7E7C;
  --hairline:#E4E4E2; --soft:#EEEEEC;
  --accent:#44586B; --fill:#44586B; --on-fill:#FFFFFF;
  --wash:color-mix(in srgb,#44586B 12%,transparent);
  --tint:#EAEEF1; --on-tint:#33424F;
  --sh:0 2px 5px rgba(31,31,30,.05), 0 24px 50px -26px rgba(31,31,30,.24);
  --quote-bg:#FAFAF9; --alt:#FCFCFB;
  --dock:#44586B; --dock-ink:#FFFFFF; --dock-body:rgba(255,255,255,.7);
}
[data-theme="dark"]{
  --canvas:#131312; --sunk:#191917; --panel:#1D1D1B;
  --ink:#F5F4F2; --body:#C7C6C2; --muted:#8B8A86;
  --hairline:#2E2E2B; --soft:#252523;
  --accent:#9EB5C8; --fill:#9EB5C8; --on-fill:#131312;
  --wash:color-mix(in srgb,#9EB5C8 12%,transparent);
  --tint:#1E2630; --on-tint:#C6D5E1;
  --sh:0 2px 5px rgba(0,0,0,.5), 0 24px 50px -26px rgba(0,0,0,.9);
  --quote-bg:#1B1B19; --alt:#171716;
  --dock:#2A3A46; --dock-ink:#F5F4F2; --dock-body:rgba(245,244,242,.66);
}

*{box-sizing:border-box;margin:0;padding:0}
body{font-family:'Plus Jakarta Sans',-apple-system,system-ui,sans-serif;background:var(--canvas);
  color:var(--body);font-size:15.5px;line-height:1.58;letter-spacing:-.006em;
  -webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}
h1,h2,h3,h4{color:var(--ink);font-weight:600;letter-spacing:-.042em;line-height:1.05}
a{color:inherit;text-decoration:none}
img{max-width:100%;height:auto}
.wrap{max-width:1120px;margin:0 auto;padding:0 36px}
.skip{position:absolute;left:-9999px}
.skip:focus{left:16px;top:16px;z-index:99;background:var(--panel);padding:10px 14px;border-radius:10px;
  box-shadow:var(--sh)}

/* ---- the bar ---- */
header#hd{position:sticky;top:0;z-index:40;background:color-mix(in srgb,var(--canvas) 86%,transparent);
  backdrop-filter:saturate(1.6) blur(14px);-webkit-backdrop-filter:saturate(1.6) blur(14px)}
header#hd.stuck{box-shadow:0 1px 0 var(--soft)}
#hd .bar{height:62px;display:flex;align-items:center;gap:24px}
.brand{display:flex;align-items:center;gap:9px;font-size:16px;font-weight:700;letter-spacing:-.035em;
  color:var(--ink)}
.mark{width:calc(17px * .7917);height:17px;background:currentColor;display:block;flex:none;
  -webkit-mask:url('../assets/mark-mask.png') no-repeat center/contain;
  mask:url('../assets/mark-mask.png') no-repeat center/contain}
#hd nav{margin-left:auto;display:flex;align-items:center;gap:22px}
#hd nav a{font-size:13.5px;font-weight:600;letter-spacing:-.015em;color:var(--muted)}
#hd nav a:hover{color:var(--ink)}
#hd nav a.on{color:var(--ink)}
/* Metrics taken off the landing page rather than re-guessed, down to the
   tracking, so a button does not change size when somebody moves between the
   two. The colour declarations carry !important for one reason: this is the
   element most likely to be inherited over by whatever context it lands in,
   and a button whose label is invisible is worse than any specificity purity. */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:10px;
  border-radius:999px;font-weight:700;letter-spacing:-.018em;font-family:inherit;
  cursor:pointer;border:1px solid transparent;
  transition:transform .2s cubic-bezier(.16,1,.3,1),box-shadow .2s,background .2s,color .2s}
.btn:hover{transform:translateY(-1px)}
.btn-fill{background:var(--fill);color:var(--on-fill)!important;box-shadow:var(--sh)}
.btn-fill:hover{box-shadow:var(--sh),0 0 0 4px color-mix(in srgb,var(--accent) 12%,transparent)}
.btn-ghost{background:var(--canvas);color:var(--ink)!important;border-color:var(--hairline)}
.btn-ghost:hover{border-color:var(--muted)}
.btn-lg{height:54px;padding:0 30px;font-size:15px}
.btn-sm{height:36px;padding:0 17px;font-size:13.5px}

/* Nothing on these pages had a focus ring except the skip link, which meant a
   keyboard could move through the whole site with no idea where it was. */
a:focus-visible,button:focus-visible,input:focus-visible,summary:focus-visible{
  outline:2px solid var(--accent);outline-offset:3px;border-radius:6px}
.btn:focus-visible,.pc:focus-visible,.cat:focus-visible{outline-offset:4px}

/* ---- the page ----
   Two widths and no third. `.doc` is a reading measure and everything long
   sits in it; `.doc.wide` is the landing page's own 1048 column, for the
   pages that are grids of cards rather than sentences. */
main.doc{padding:56px 0 0}
/* padding-inline, not the shorthand. `.doc .grid` is two classes and every
   section on these pages carries both `sect` and `grid`, so a `padding:0 36px`
   here quietly won against each section's own top padding and stacked them all
   flush against each other. */
.doc .grid{max-width:1120px;margin:0 auto;padding-inline:36px}
/* 660, not 720. At 720 with this size the line ran to 82 characters, which is
   past the point where the eye starts losing its place returning to the left.
   660 is about 74.

   Centred in the 1048 column, not pinned left. Left-aligned it sat with 590px
   of nothing beside it and read as a page missing its sidebar. The TEXT stays
   left-aligned; it is the measure that moves. */
.doc .grid>*{max-width:660px;margin-inline:auto}
.doc.wide .grid>*{max-width:none}

.masthead{padding-top:26px}
.kicker{font-size:11.5px;letter-spacing:.15em;font-weight:700;color:var(--accent);margin-bottom:20px}
.masthead h1{font-size:clamp(30px,3.8vw,44px);letter-spacing:-.046em;text-wrap:balance}
.masthead .deck{font-size:17px;line-height:1.6;color:var(--muted);margin-top:20px;text-wrap:balance}
.masthead .deck a{color:var(--accent);font-weight:600}
.meta{margin-top:24px;display:flex;align-items:center;gap:10px;font-size:13px;color:var(--muted)}
.meta .pill{background:var(--tint);color:var(--on-tint);font-size:11px;letter-spacing:.1em;
  font-weight:800;padding:6px 11px;border-radius:999px}
/* NOT .meta. That one is a flex row for the pill-and-date line, so a sentence
   put in it had every phrase and every <strong> turned into a flex item with a
   10px gap between them, and the date came out stacked in the middle of the
   line. This is a sentence, so it is set as one. */
.stamp{margin:-10px 0 28px;font-size:13px;line-height:1.55;color:var(--muted)}
.stamp strong{color:var(--body);font-weight:700}

/* ---- a section on an index page ---- */
/* 66, and 80 for the one that follows a masthead: a section heading landing
   straight under a deck or a search box reads as part of it. */
.sect{padding-top:76px}
.masthead+.sect{padding-top:84px}
.sect-h{display:flex;align-items:baseline;gap:16px;margin-bottom:22px}
.sect-h h2{font-size:22px;letter-spacing:-.04em}
.sect-h p{font-size:14px;color:var(--muted)}
.sect-h .more{margin-left:auto;font-size:13.5px;font-weight:700;color:var(--accent)}

/* ---- browse by topic ----
   The thing worth stealing from Muse and Chorus: six tiles that say what the
   blog is about before anybody has read a word of it. Tiles are links, not
   buttons, so the categories still work with scripting off, and the filter
   upgrades them in place. */
.cats{display:grid;grid-template-columns:repeat(3,1fr);gap:14px}
.cat{display:flex;flex-direction:column;gap:9px;padding:20px 22px 22px;border-radius:16px;
  background:var(--sunk);border:1px solid transparent;cursor:pointer;text-align:left;
  font-family:inherit;transition:background .25s,border-color .25s,transform .25s cubic-bezier(.16,1,.3,1)}
.cat:hover{transform:translateY(-2px);background:var(--panel);border-color:var(--soft);box-shadow:var(--sh)}
/* A chosen tile needs to read as chosen across a whole row at a glance, and a
   white-on-off-white swap does not do that in either theme, let alone in dark
   where the two grounds are four points apart. The accent ring does. */
.cat[aria-pressed="true"]{background:var(--panel);border-color:var(--accent);
  box-shadow:0 0 0 1px var(--accent),var(--sh)}
.cat[aria-pressed="true"] .ic{background:var(--fill);color:var(--on-fill)}
.cat .ic{width:34px;height:34px;border-radius:11px;background:var(--tint);color:var(--accent);
  display:grid;place-items:center;flex:none}
.cat .ic svg{width:18px;height:18px}
.cat .t{font-size:15px;font-weight:700;letter-spacing:-.03em;color:var(--ink)}
.cat .d{font-size:13.5px;line-height:1.5;color:var(--muted)}
.cat .n{margin-left:auto;font-size:12px;font-weight:700;color:var(--muted)}

/* ---- a grid of cards ---- */
.pcs{display:grid;grid-template-columns:repeat(3,1fr);gap:14px}
.pcs.two{grid-template-columns:repeat(2,1fr)}
/* --hairline rather than --soft on the border. In dark mode a panel is #1D1D1B
   on a #131312 ground and the softer line left the cards barely legible as
   objects at all. */
.pc{display:flex;flex-direction:column;gap:8px;padding:22px 24px 24px;border-radius:16px;
  background:var(--panel);border:1px solid var(--hairline);
  transition:transform .25s cubic-bezier(.16,1,.3,1),box-shadow .25s,border-color .25s}
.pc:hover{transform:translateY(-2px);box-shadow:var(--sh);border-color:var(--hairline)}
.pc-cat{font-size:10.5px;letter-spacing:.14em;font-weight:800;color:var(--accent)}
.pc-t{font-size:16px;font-weight:700;letter-spacing:-.032em;line-height:1.24;color:var(--ink);
  text-wrap:balance}
.pc-x{font-size:13.5px;line-height:1.55;color:var(--muted)}
.pc-m{margin-top:auto;padding-top:10px;font-size:12.5px;color:var(--muted)}
.pc[hidden]{display:none}
.empty{padding:34px 0;font-size:15px;color:var(--muted)}

/* ---- search ----
   Same shape as the FAQ's on the landing page, because it does the same job
   and a visitor should not have to learn a second one. */
.search{margin-top:30px;position:relative;max-width:440px}
.search svg{position:absolute;left:15px;top:50%;transform:translateY(-50%);width:16px;height:16px;
  color:var(--muted);pointer-events:none}
/* The landing page's FAQ search, at a page-header size: a rounded rectangle
   rather than a pill, a hairline border, and the same focus ring. */
.search input{width:100%;height:54px;padding:0 46px 0 44px;border-radius:14px;
  border:1px solid var(--hairline);background:var(--canvas);color:var(--ink);
  font-family:inherit;font-size:14.5px;letter-spacing:-.01em;outline:none;
  transition:border-color .25s,box-shadow .25s}
.search input:focus{border-color:var(--accent);
  box-shadow:0 0 0 3px color-mix(in srgb,var(--accent) 14%,transparent)}
.search kbd{position:absolute;right:14px;top:50%;transform:translateY(-50%);font:inherit;
  font-size:11px;font-weight:700;color:var(--muted);background:var(--panel);border:1px solid var(--soft);
  border-radius:6px;padding:2px 7px}

/* ---- the long read ----
   One column, one measure, and furniture that repeats: a note, a table, a
   mid-page call, a set of questions. A post and a comparison are the same
   page with different words in them. */
.article{padding-top:54px;font-size:16.5px;line-height:1.7}
.article h2{font-size:26px;letter-spacing:-.04em;margin:44px 0 14px}
.article h3{font-size:19px;letter-spacing:-.035em;margin:32px 0 10px}
.article h2:first-child,.article h3:first-child{margin-top:0}
.article p{margin-bottom:18px}
/* The opening paragraph is the answer to the title, so it is set in ink rather
   than body colour. It is NOT set larger: one size for every line of reading
   text on the page, headings excepted. */
.article>p:first-of-type{color:var(--ink)}
.article p:last-child{margin-bottom:0}
/* :not(.btn) on both, and it is not fussiness. `.article a` is one class and
   one element, which beats `.btn-fill`'s single class, so every button inside a
   long page was being repainted accent-on-accent: the text and the fill were
   the identical colour and the label vanished completely. The nav had the same
   fault from `#hd nav a`. A button is not prose and must opt out of prose. */
.article a:not(.btn){color:var(--accent);font-weight:600;text-decoration:underline;
  text-decoration-color:color-mix(in srgb,var(--accent) 30%,transparent);text-underline-offset:3px}
.article a:not(.btn):hover{text-decoration-color:var(--accent)}
.article .btn{text-decoration:none}
/* The markers were rendering OUTSIDE the column. A list marker is drawn to the
   left of the item box by default, so with no padding to sit in it hung past
   the measure every other block on the page starts at, and a bulleted section
   read as if it had slipped left. Own bullets, positioned inside. */
.article ul{list-style:none;margin:0 0 18px;padding:0}
.article ul>li{position:relative;padding-left:22px}
.article ul>li::before{content:'';position:absolute;left:3px;top:.66em;width:5px;height:5px;
  border-radius:50%;background:var(--muted)}
.article ol{margin:0 0 18px;padding-left:24px}
.article ol>li{padding-left:2px}
.article li{margin-bottom:8px}
.article li::marker{color:var(--muted)}
.article strong{color:var(--ink);font-weight:700}
.article code{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:14px;
  background:var(--sunk);padding:2px 6px;border-radius:6px;color:var(--ink)}
.article pre{margin:26px 0;padding:20px 22px;border-radius:14px;background:var(--sunk);
  overflow-x:auto}
.article pre code{background:none;padding:0;border-radius:0;font-size:13.5px;line-height:1.6;
  white-space:pre;color:var(--body)}

/* An aside, not a grey rule. The page separates with space and with boxes,
   never with a hairline across the column. */
.note{margin:26px 0;padding:20px 24px;border-radius:14px;background:var(--sunk);
  font-size:16.5px;line-height:1.65}
.note b{display:block;color:var(--ink);font-size:13px;letter-spacing:.06em;text-transform:uppercase;
  margin-bottom:7px}
.note.tint{background:var(--tint);color:var(--on-tint)}
.note.tint b{color:var(--on-tint)}

.tablewrap{margin:26px 0;overflow-x:auto;border-radius:14px;border:1px solid var(--soft)}
table{width:100%;border-collapse:collapse;font-size:14.5px}
th,td{padding:13px 16px;text-align:left;vertical-align:top}
thead th{font-size:11px;letter-spacing:.12em;font-weight:800;color:var(--muted);background:var(--sunk)}
/* The label and the value columns do not wrap. Left to itself the middle
   column took the width and squeezed "Coding agent" and "You have it" onto two
   lines each, which made a three-row table look like a six-row one. */
th:first-child,td:first-child,th:last-child,td:last-child{white-space:nowrap}
/* Striped, not ruled. A hairline across every row is the separator this site
   does not use anywhere else, and on a table the alternating ground reads
   faster anyway. */
tbody tr:nth-child(even){background:var(--sunk)}
tbody td:first-child{color:var(--ink);font-weight:700}
td .yes{color:var(--accent);font-weight:700}
td .no{color:var(--muted)}

/* The one interruption a long page gets, and it earns it by arriving after
   the argument rather than before it. */
/* Both buttons, the same pair as the closing block, so the ask never changes
   shape halfway down a page. On this ground the accent fill would sit almost
   on top of the card's own colour, so the primary goes white and the secondary
   is outlined in the card's own text colour. */
/* One row, not a stack. The words and the buttons together have to fit the
   660 measure or the flex wraps and the card comes out twice the height it
   needs: two lines of copy at 320px, two buttons at 265, and the 24 between
   them. That is why the lines here are as short as they are, and why the
   buttons take a tighter inset than they do in the closing block. */
.midcta{margin:38px 0;padding:20px 26px;border-radius:18px;background:var(--dock);
  color:var(--dock-ink);display:flex;align-items:center;gap:26px;flex-wrap:wrap}
/* Words to the left wall, buttons to the right one. The box itself is centred
   on the page by the column it sits in, which is the part that has to hold. */
.midcta>div{flex:1 1 220px;min-width:0}
.midcta b{display:block;font-size:16px;letter-spacing:-.035em;line-height:1.25}
.midcta p{margin:3px 0 0;font-size:13.5px;line-height:1.45;color:var(--dock-body)}
.midcta .paths{margin-left:auto;flex:none;display:flex;gap:10px}
.midcta .btn-lg{height:46px;padding:0 22px;font-size:14.5px}
.midcta .btn-fill{background:var(--canvas);color:var(--ink)!important;box-shadow:none}
.midcta .btn-fill:hover{box-shadow:0 0 0 4px rgba(255,255,255,.14)}
.midcta .btn-ghost{background:transparent;color:var(--dock-ink)!important;
  border-color:color-mix(in srgb,var(--dock-ink) 34%,transparent)}
.midcta .btn-ghost:hover{border-color:var(--dock-ink)}

/* The grey variant, for a call to action that is NOT part of the navy group at
   the top of the page. Two navy boxes at the foot of /start/ read as the same
   announcement twice; one grey closer reads as the end of the page. */
/* The closer. Grey, like the box it replaced, and told apart from the help row
   above it by its button rather than by its colour: one button, square-ish
   against the pills everywhere else on the site, and no price on it. */
.midcta.soft{background:var(--sunk);color:var(--ink);padding:24px 30px}
.midcta.soft b{color:var(--ink);font-size:17px;letter-spacing:-.036em}
/* --body, not --muted: muted on sunk measures 3.8:1, under the floor. */
.midcta.soft p{color:var(--body);font-size:14px;margin-top:5px;text-wrap:balance}
.midcta.soft .btn-fill{background:var(--dock);color:var(--dock-ink)!important;
  border-radius:12px;height:48px;padding:0 30px;font-size:15px;box-shadow:none}
.midcta.soft .btn-fill:hover{box-shadow:0 0 0 4px color-mix(in srgb,var(--dock) 15%,transparent)}
/* Studio as the second choice rather than the second-best one: a white box with
   the accent on it, the same square corner as Pro beside it. In dark it inverts
   with the canvas, so it stays the lighter-weight of the two either way. */
.midcta.soft .btn-ghost{background:var(--canvas);color:var(--accent)!important;
  border-color:var(--hairline);border-radius:12px;height:48px;padding:0 28px;font-size:15px}
.midcta.soft .btn-ghost:hover{border-color:var(--accent)}

/* The four buttons in these two rows sit on the same four vertical lines. CSS
   cannot make two separate groups share intrinsic widths, so the columns are
   fixed: 148px against a 95px "Email Support", the longest of the four labels,
   and the buttons fill them. Wider than this and the CTA subtitle loses a line. */
.help.bare .paths,.midcta.soft .paths{display:grid;grid-template-columns:148px 148px;gap:12px}
.help.bare .paths .btn,.midcta.soft .paths .btn{width:100%;padding:0}
@media(max-width:560px){
  .help.bare .paths,.midcta.soft .paths{grid-template-columns:1fr 1fr;width:100%}
}

/* Grey, not the accent. The help row is the quiet one of the two. */
.help.bare .btn-fill{background:var(--soft);color:var(--ink)!important;box-shadow:none;
  border-color:transparent}
.help.bare .btn-fill:hover{background:var(--hairline)}

/* Stripped of its box, because it now sits directly above one. */
/* Same 30px inset as the boxed closer beneath it, on both sides, so the two
   blocks are parallel and the only difference between them is the background. */
.help.bare{background:none;padding:0 30px;margin-top:30px}
/* The 26px on the right is the boxed CTA's own padding, so the two button rows
   below each other line up. The text keeps the page's single left edge. */

/* ---- questions ---- */
/* Each question is its own rounded card with space around it, exactly as the
   landing page's FAQ does it. It was a stack of hairline-separated rows, which
   is both a different pattern from the rest of the site and the one separator
   this site has decided against. */
/* The questions start further below their heading than the other sections do,
   because each one is a card rather than a paragraph: a card sitting at the
   usual paragraph distance reads as attached to the title above it. */
.faq{margin-top:26px;display:grid;gap:8px}
.faq details{background:var(--sunk);border-radius:14px;padding:16px 20px;
  transition:background .3s,box-shadow .3s}
.faq details[open]{background:var(--alt);box-shadow:0 0 0 1px var(--soft)}
.faq summary{list-style:none;cursor:pointer;display:flex;align-items:flex-start;gap:14px;
  font-size:16.5px;font-weight:700;letter-spacing:-.03em;color:var(--ink);line-height:1.35}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:'';margin-left:auto;width:11px;height:11px;flex:none;margin-top:6px;
  border-right:2px solid var(--muted);border-bottom:2px solid var(--muted);
  transform:rotate(45deg);transition:transform .25s}
.faq details[open] summary::after{transform:rotate(-135deg)}
.faq .a{padding-top:11px;font-size:16.5px;line-height:1.7;color:var(--body)}

/* ---- the close ---- */
/* Set its own size rather than inheriting the article's 17px. A call to action
   is chrome, not prose, and it reads a size too big when it borrows from the
   paragraphs above it. */
.endcta{margin:72px 0 0;padding:48px 24px;border-radius:24px;background:var(--sunk);
  text-align:center;font-size:15.5px;line-height:1.58}
.endcta h2{font-size:clamp(24px,3vw,32px);letter-spacing:-.045em;text-wrap:balance}
.endcta p{margin:14px auto 0;max-width:460px;font-size:15.5px;color:var(--muted)}
.endcta .paths{margin-top:26px;display:flex;justify-content:center;gap:12px;flex-wrap:wrap}
/* The index pages close on a sentence rather than a button. */
.closing{margin-top:14px;font-size:15px;color:var(--muted);max-width:560px;text-wrap:balance}

/* ---- keep reading ---- */
.rel{padding-top:56px}
.rel h2{font-size:20px;letter-spacing:-.04em;margin-bottom:18px}

/* ---- footer ---- */
/* ---------- the footer ----------
   The landing page's footer, ported here so every page on the site ends the
   same way: a wash rather than a rule, six columns, and the brand at the head
   of the row instead of stacked above it. */
footer{padding:96px 0 40px;background:linear-gradient(180deg,var(--canvas) 0%,var(--wash) 46%)}
.cols{display:grid;grid-template-columns:220px repeat(4,1fr);gap:40px}
footer .who .brand{display:inline-flex;align-items:center;gap:10px;font-weight:800;font-size:25px;
  color:var(--accent);letter-spacing:-.048em;text-decoration:none;line-height:1}
/* Nudged 1px down: align-items centres the two BOXES, and the text box carries
   descender room the mark does not. */
footer .who .mark{position:relative;top:1px;width:calc(22px * .7917);height:22px}
/* 14ch, so it breaks where it was written to break: "Your own agentic" then
   "support centre." */
footer .who p{margin-top:18px;font-size:14px;color:var(--muted);line-height:1.5;max-width:14ch}
footer .follow{margin-top:24px;display:inline-flex;align-items:center;gap:10px;height:40px;
  padding:0 16px;border-radius:10px;background:var(--ink);color:var(--canvas);
  font-size:14px;font-weight:700;letter-spacing:-.02em;text-decoration:none;
  transition:transform .3s cubic-bezier(.16,1,.3,1),opacity .3s}
footer .follow:hover{transform:translateY(-1px);opacity:.9}
footer .follow svg{width:15px;height:15px;fill:currentColor}
footer .col{display:flex;flex-direction:column}
footer .col h5{font-size:14px;font-weight:700;color:var(--ink);letter-spacing:-.024em;
  margin-bottom:20px;text-transform:none}
footer .col a{display:block;font-size:14px;color:var(--muted);text-decoration:none;
  letter-spacing:-.014em;padding:6px 0;white-space:nowrap;transition:color .25s}
footer .col a:hover{color:var(--ink)}
footer .col a.dead{cursor:default}
footer .col a.dead:hover{color:var(--muted)}
footer .base{margin-top:80px}
footer .base .cr{font-size:14px;color:var(--muted);letter-spacing:-.014em}
@media(max-width:1080px){
  footer .cols{grid-template-columns:max-content repeat(4,max-content);
    justify-content:space-between;gap:44px 16px}
  footer .who p{max-width:16ch}
  footer .who .brand{font-size:21px}
}
@media(max-width:760px){
  footer .cols{grid-template-columns:1fr 1fr;gap:38px 24px}
  footer .col a{white-space:normal}
  footer .base{margin-top:56px}
}

@media(max-width:1040px){
  .cats,.pcs{grid-template-columns:repeat(2,1fr)}
}
@media(max-width:720px){
  .wrap{padding:0 22px}
  .doc .grid{padding-inline:22px}
  .cats,.pcs,.pcs.two{grid-template-columns:1fr}
  #hd nav{gap:14px}
  #hd nav a:not(.on):not(.buy){display:none}
  .article{font-size:16px}
  .midcta .paths{margin-left:0}
  .endcta{border-radius:18px;padding:34px 20px}
}

/* ---- the compare hub's three kinds of page ----
   Fifteen cards of one shape read as one long undifferentiated list, and the
   three groups on that page are answering three different questions. Same grid,
   three signatures: a roundup is about somebody else's product so it carries
   their initial, a guide names nobody so it drops the white card onto the
   page's own grey, and a head to head is a pair so it shows one. */
.pc.rup{flex-direction:row;align-items:flex-start;gap:14px}
/* The competitor's own mark where they have one, a letter where they do not.
   Grey at rest and colour on hover: six brand palettes in a row would be the
   loudest thing on a page whose accent count is one, and would make the
   competitors the most eye-catching element on a page selling Docket. At 38px
   inside a card, against a page of one accent, they read as identification
   rather than as decoration.

   Self-hosted in assets/marks. Hotlinking a competitor's favicon leaks every
   visitor to their server and breaks the day they redesign. */
.pc.rup .mono{width:38px;height:38px;flex:none;border-radius:11px;background:#F1F1EF;
  color:#3F3F3E;display:grid;place-items:center;font-size:14px;font-weight:800;
  letter-spacing:-.02em;overflow:hidden}
/* In colour, and full bleed. These are app icons: they arrive with their own
   ground and their own corner radius, so the right thing is to show them as
   what they are rather than draining them to grey inside a second tile.
   Greyscale was the wrong call and it looked it, a row of muddy stickers
   rather than a row of products somebody might recognise.

   The exception is a mark that ships transparent, which needs a ground of its
   own or it disappears against a dark card. Those carry .tile, and so do the
   two chips that are still a letter. */
.pc.rup .mono{background:none}
.pc.rup .mono:not(.img),
.pc.rup .mono.tile{background:#F1F1EF}
.pc.rup .mono img{width:38px;height:38px;object-fit:cover;border-radius:11px;display:block}
/* Inset on the tile, not full bleed. UserJot's mark is a filled dark circle
   that reaches the edge of its own frame, so a ground behind it at full bleed
   is a ground nobody can see, and on a dark card the circle merged with the
   card. Four pixels of tile showing around it is the whole fix. */
.pc.rup .mono.tile img{width:30px;height:30px;margin:4px;border-radius:9px}
.pc.rup .tx{display:flex;flex-direction:column;gap:6px;min-width:0}

.pcs.guides .pc{background:var(--sunk);border-color:transparent}
.pcs.guides .pc:hover{background:var(--panel);border-color:var(--hairline)}
.pcs.guides .pc-cat{color:var(--muted)}

/* The pair IS the title here, so there is no bold line under it repeating the
   two names it already carries. */
.pc.h2h .vs{display:flex;align-items:center;gap:8px;margin-bottom:6px;flex-wrap:wrap}
.pc.h2h .vs span{height:26px;padding:0 10px;border-radius:8px;display:grid;place-items:center;
  font-size:12px;font-weight:800;letter-spacing:-.01em}
.pc.h2h .vs .a{background:var(--fill);color:var(--on-fill)}
.pc.h2h .vs .b{background:var(--sunk);color:var(--ink)}
.pc.h2h .vs em{font-style:normal;font-size:11px;font-weight:800;letter-spacing:.1em;
  color:var(--muted)}
.pc.h2h .pc-x{font-size:14px}

/* ---- the three-year cost calculator ----
   It lives inside a post rather than on a page of its own, because
   "canny pricing calculator" returns no autocomplete at all: it is not a search
   target, it is what makes the pricing post worth citing. */
.calc{margin:34px 0;padding:24px 26px;border-radius:20px;background:var(--sunk)}
.calc .lbl{margin:0 0 18px;font-size:11.5px;font-weight:800;letter-spacing:.1em;
  text-transform:uppercase;color:var(--muted)}
.calc-in{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;margin-bottom:22px}
.calc-in label{display:block;font-size:12.5px;font-weight:700;letter-spacing:-.01em;
  color:var(--body)}
.calc-in input,.calc-in select{display:block;width:100%;margin-top:7px;height:42px;
  padding:0 12px;border-radius:11px;border:1px solid var(--hairline);
  background:var(--canvas);color:var(--ink);font-family:inherit;font-size:15px;
  font-weight:600;letter-spacing:-.01em}
.calc-in input:focus,.calc-in select:focus{outline:2px solid var(--accent);
  outline-offset:2px;border-color:transparent}
.article .calc .tablewrap{margin:0}
.calc tbody tr.win td{font-weight:700;color:var(--ink)}
.calc tbody td em{font-style:normal;font-weight:400;color:var(--muted);font-size:13px}
.article .calc .calc-note{margin:16px 0 0;font-size:13px;line-height:1.55;color:var(--muted)}
@media(max-width:640px){.calc-in{grid-template-columns:1fr}}

/* ---- the legal pages ----
   Privacy and terms. Both are mostly tables of prose, and the shared rule that
   keeps the FIRST and LAST cell of a table on one line exists for short cells
   like "Yes" and "$99". Here those cells are whole sentences, so it is lifted,
   and the tables are allowed past the 660px reading measure because a
   three-column table of prose inside it is unreadable. */
/* A legal page is read by jumping, not by scrolling, so it gets a contents
   list. Two columns, because fourteen and twenty sections in one column is a
   wall in its own right. */
.toc{margin:30px 0 8px;padding:22px 26px;border-radius:18px;background:var(--sunk)}
.toc .lbl{margin:0 0 14px;font-size:11.5px;font-weight:800;letter-spacing:.1em;
  text-transform:uppercase;color:var(--muted)}
.article .toc ol{list-style:none;margin:0;padding:0;columns:2;column-gap:32px}
.article .toc li{margin:0;padding:0;break-inside:avoid}
.article .toc a{display:block;padding:5px 0;font-size:14.5px;line-height:1.4;
  color:var(--body);text-decoration:none;letter-spacing:-.014em}
.article .toc a:hover{color:var(--ink);text-decoration:underline;text-underline-offset:3px}
@media(max-width:620px){.article .toc ol{columns:1}}

/* Each heading is a citable clause, so it carries an id and a target you can
   see. The marker only appears on hover and on keyboard focus, so it never
   competes with the heading itself. */
.legal h2{position:relative}
.legal h2 .anchor{position:absolute;left:-24px;top:50%;transform:translateY(-50%);
  width:20px;text-align:center;color:var(--muted);opacity:0;text-decoration:none;
  font-size:17px;font-weight:400;transition:opacity .2s}
.legal h2:hover .anchor,.legal h2 .anchor:focus-visible{opacity:1}
@media(max-width:1100px){.legal h2 .anchor{display:none}}

/* The four-line answer at the top of the privacy page is the only part most
   people will read, so it is set apart rather than left as four paragraphs. */
.tldr{margin:30px 0 8px;padding:24px 26px;border-radius:18px;background:var(--tint);
  color:var(--on-tint)}
.article .tldr p{margin:0 0 13px;font-size:15.5px;line-height:1.6;color:var(--on-tint)}
.article .tldr p:last-child{margin-bottom:0}
.article .tldr strong{color:var(--on-tint)}

/* The shared nowrap on first and last cells exists for short values like "Yes"
   and "$99". In an article those cells are prose, and holding them on one line
   made a four-column table demand 1,340px inside a 780px wrapper. */
.article td,.article th{white-space:normal}

/* A three-column table of prose does not fit a phone, and a box that scrolls
   sideways with no way to tell it scrolls hides content. These become labelled
   blocks instead, which is the same information in the order it is read.
   Applies to every article, not just the legal pages: a blog post's pricing
   table is the argument, so it is the last thing that should hide. */
@media(max-width:560px){
  .article table.stack thead{display:none}
  .article table.stack,.article table.stack tbody,.article table.stack tr,
  .article table.stack td{display:block;width:auto}
  .article table.stack tr{padding:14px 16px}
  .article table.stack td{padding:0 0 10px}
  .article table.stack td:last-child{padding-bottom:0}
  .article table.stack td[data-label]::before{content:attr(data-label);display:block;
    font-size:10.5px;font-weight:800;letter-spacing:.1em;text-transform:uppercase;
    color:var(--muted);margin-bottom:3px}
  .article table.stack tbody td:first-child{font-weight:700;color:var(--ink)}
}
.article tbody td:first-child{min-width:8.5rem}
/* Tables break out past the 660px reading measure, because four columns inside
   it scroll even on a desktop. Applies to every article, not just legal. */
.doc .article .tablewrap{max-width:780px}
.legal h2{scroll-margin-top:80px}
@media(max-width:820px){.doc .article .tablewrap{max-width:660px}}
@media(max-width:560px){
  .article table{font-size:13.5px}
  .article th,.article td{padding:11px 12px}
  .article tbody td:first-child{min-width:0}
}

/* ---- print ----
   A legal page is the one page anybody actually prints or saves as a PDF, so
   the chrome goes, the palette is forced light whatever the screen was set to,
   and a section does not start on the last line of a page. */
@media print{
  :root{--canvas:#fff;--sunk:#fff;--tint:#fff;--on-tint:#000;--ink:#000;--body:#222;
    --muted:#444;--hairline:#bbb;--soft:#ddd;--alt:#fff;--dock:#fff;--dock-ink:#000}
  html,body{background:#fff;color:#000}
  #hd,footer,.skip,.toc,.anchor,.midcta,.help,.btn{display:none!important}
  .doc .grid{max-width:none;padding-inline:0}
  .doc .grid>*,.doc .legal .tablewrap{max-width:none}
  .masthead{padding-top:0}
  .masthead h1{font-size:26pt}
  .article{font-size:10.5pt;line-height:1.5}
  .article h2{font-size:14pt;margin-top:22pt;break-after:avoid;page-break-after:avoid}
  .tldr,.note,.summary{border:1px solid #bbb;border-radius:0}
  .tablewrap{border:1px solid #bbb;border-radius:0;overflow:visible}
  table{font-size:9.5pt}
  thead th{background:#eee}
  tbody tr:nth-child(even){background:#f6f6f6}
  tr,td,th{break-inside:avoid;page-break-inside:avoid}
  a{color:#000;text-decoration:underline}
  .article a[href^="http"]::after{content:" (" attr(href) ")";font-size:8.5pt;color:#555;
    word-break:break-all}
}

/* ---- the setup pages ----
   /start/ and /welcome/ are the only pages on the site somebody reads while
   DOING something, one hand on the keyboard. Everything here is in service of
   that: know what you need before you begin, see how far along you are, and
   know when you are finished. */

/* Everything you need before step one, as ONE object rather than three loose
   chips. Three chips floating at the article edge fought the step column for the
   left margin and wrapped two-then-one; a card is an object, so its own edge is
   legitimate and its contents can sit on an even three-column grid. */
.pre{margin-top:32px;padding:22px 24px;border-radius:18px;background:var(--sunk)}
/* The one-paragraph answer to "is free enough for me?", in the same grey box as
   the shopping list below it, so the two summaries look like a pair. */
.summary{margin-top:30px;padding:22px 24px;border-radius:18px;background:var(--sunk)}
.article .summary p:not(.lbl){margin:0;font-size:16px;line-height:1.62;color:var(--body)}
.article > .summary + .scope{margin-top:14px}
.pre .lbl,.summary .lbl{margin:0 0 15px;font-size:11.5px;font-weight:800;letter-spacing:.1em;
  text-transform:uppercase;color:var(--muted)}
.pre .row{display:grid;grid-template-columns:repeat(3,1fr);gap:16px}
.pre .it{display:flex;align-items:flex-start;gap:11px;min-width:0}
.pre .it svg{width:17px;height:17px;flex:none;color:var(--accent);margin-top:1.5px}
.pre .it b{display:block;font-size:14.5px;font-weight:700;letter-spacing:-.025em;
  color:var(--ink);line-height:1.35}
.pre .it span{display:block;margin-top:1px;font-size:13.5px;color:var(--muted);line-height:1.4}
@media(max-width:640px){.pre .row{grid-template-columns:1fr;gap:14px}}

/* A rail down the numbers, so three blocks read as one sequence. It stops at
   the last number rather than running past it, which is the difference between
   a sequence that ends and a list that has been cut off. */
/* Scoped under .article, because .article ol carries a padding-left and a margin
   reset that outrank a bare .stp and were shunting the whole step column 26px
   right of the card above it. */
.article .stp{list-style:none;display:grid;gap:0;margin:40px auto 0;padding:0}
.article .stp li{position:relative;display:grid;grid-template-columns:34px 1fr;gap:20px;
  align-items:start;padding:0 0 38px}
.article .stp li:last-child{padding-bottom:0}
.stp li::before{content:'';position:absolute;left:16px;top:38px;bottom:6px;width:2px;
  background:var(--soft);border-radius:2px}
.stp li:last-child::before{display:none}
.stp li>div{min-width:0}
.stp .n{position:relative;z-index:1;width:34px;height:34px;border-radius:12px;background:var(--tint);
  color:var(--on-tint);font-size:14px;font-weight:800;display:grid;place-items:center;
  font-variant-numeric:tabular-nums}
.stp b{display:block;font-size:17.5px;color:var(--ink);font-weight:700;letter-spacing:-.032em;
  margin:5px 0 10px}
.stp p{margin:0 0 14px}
.stp p:last-child{margin-bottom:0}

.line{margin-top:16px;background:var(--sunk);border-radius:12px;padding:13px 15px;
  display:flex;align-items:center;gap:12px;flex-wrap:wrap}
.line code{background:none;padding:0;font-size:13.5px;flex:1;min-width:0;line-height:1.6}

/* The prompt rows are their own thing: the button is parked in the top right
   corner so the line beneath it can run to one or two lines and look deliberate
   either way, rather than a button floating beside a wrapped paragraph. */
.line.prompt{display:block;padding:14px 16px;padding-right:88px;position:relative}
.line.prompt code{display:block;font-size:13.5px;line-height:1.7}
.copy{border:1px solid var(--hairline);background:var(--canvas);color:var(--muted);
  font-family:inherit;font-size:12.5px;font-weight:700;height:34px;padding:0 14px;
  border-radius:9px;cursor:pointer;flex:none}
.line.prompt .copy{position:absolute;top:11px;right:11px}
.copy:hover{color:var(--ink);border-color:var(--muted)}
@media(max-width:520px){
  .line.prompt{padding-right:16px}
  .line.prompt .copy{position:static;margin-top:12px}
}

/* Knowing you have finished is a step in itself, and the one nobody writes.
   The heading is its own line: it was reading as the opening clause of the
   sentence beneath it, which left that sentence starting in lower case. */
.article > .done{margin-top:28px}
.done{margin-top:18px;padding:16px 18px;border-radius:14px;background:var(--tint);
  color:var(--on-tint);display:flex;align-items:flex-start;gap:12px}
.done>svg{width:18px;height:18px;flex:none;margin-top:3px}
.done b{display:block;font-size:15px;font-weight:700;letter-spacing:-.025em;
  color:var(--on-tint);margin-bottom:4px}
.done p{margin:0;font-size:14.8px;line-height:1.6;color:var(--on-tint)}
.done code{background:rgba(0,0,0,.055);color:inherit;padding:1px 6px;border-radius:6px;
  font-size:13px}

/* Questions before the email address, because most of them have been asked.
   Text left, buttons right, matching every other call to action on the site. */
.help{margin-top:54px;padding:24px;border-radius:20px;background:var(--sunk);
  display:flex;align-items:center;gap:22px;flex-wrap:wrap;text-align:left}
.help>div{flex:1 1 200px;min-width:0}
.help b{display:block;font-size:17px;color:var(--ink);letter-spacing:-.035em}
.help p{margin:5px 0 0;max-width:46ch;font-size:15px;color:var(--muted);line-height:1.55;
  text-wrap:balance}
.help .paths{margin-left:auto;flex:none;display:flex;gap:10px}
.help .paths .btn{height:44px;padding:0 20px;font-size:14.5px}
@media(max-width:720px){
  .stp li{grid-template-columns:30px 1fr;gap:16px}
  .stp li::before{left:14px}
  .stp .n{width:30px;height:30px}
}
@media(max-width:640px){
  .help{padding:22px}
  .help .paths{margin-left:0;width:100%}
  .help .paths .btn{flex:1}
}

/* The create-from-template button and its tier label, on /welcome/. */
/* Somebody arriving without ?tier sees both. Two identical black buttons side by
   side told them nothing, so the tier leads each row and the rows stack. */
.make{margin-top:18px;display:grid;grid-template-columns:auto auto;gap:10px 14px;
  align-items:center;justify-content:start}
.make .tier{justify-self:start;min-width:84px;text-align:center;padding:4px 11px;
  border-radius:8px;background:var(--tint);color:var(--on-tint);font-size:11.5px;
  font-weight:800;letter-spacing:.08em;text-transform:uppercase}
@media(max-width:560px){
  .make{grid-template-columns:1fr;gap:8px}
  .make .tier{min-width:0;justify-self:start}
  .make .btn{width:100%}
  .make .tier+.btn{margin-bottom:6px}
}

/* Free at a glance, on /start/. Somebody who clicked "Start Free" has decided
   nothing yet, so the two columns sit side by side at equal weight rather than
   burying the second half in a paragraph.

   Both cards are the same navy. What free DOES is white; what it does not is
   the same navy, dimmer. That is the whole point of one surface rather than
   two: the missing half is not an error state, it is the same list with the
   lights off, which is a truer picture than a red panel next to a green one. */
.scope{margin-top:26px;display:grid;grid-template-columns:1fr 1fr;gap:14px}
.article > .scope:first-child{margin-top:30px}
/* The same 14px the two cards are apart, so the three navy blocks read as one
   group rather than a comparison and, separately, an advert. Then a real gap
   below it, because what follows is a different job: deciding, then doing. */
.scope + .midcta{margin-top:14px;margin-bottom:62px}
.scope .cx{padding:22px 24px;border-radius:18px;background:var(--dock);
  color:var(--dock-ink);display:flex;flex-direction:column}
.scope h4{margin:0 0 16px;font-size:11.5px;font-weight:800;letter-spacing:.1em;
  text-transform:uppercase;color:var(--dock-body)}
.article .scope ul{list-style:none;margin:0;padding:0;display:grid;gap:11px}
.article .scope ul>li{padding:0;display:flex;gap:11px;font-size:14.5px;line-height:1.45}
.article .scope ul>li::before{content:none}
.scope li svg{width:15px;height:15px;flex:none;margin-top:2.5px}
.scope .cx.no li,.scope .cx.no li svg{color:var(--dock-ink)}
.scope .cx.yes li,.scope .cx.yes li svg{color:var(--dock-body)}
.scope .cx .end{margin:auto 0 0;padding-top:18px;font-size:13.5px;font-weight:700;
  letter-spacing:-.02em;color:var(--dock-ink)}
.scope .cx.yes .end{color:var(--dock-body)}
@media(max-width:640px){.scope{grid-template-columns:1fr}}

/* The one panel on a setup page that must not be skimmed: the invitation on
   /welcome/, what free does and does not do on /start/. */
.watch{margin:26px 0 0;padding:22px 24px;border-radius:16px;background:var(--tint);
  color:var(--on-tint)}
.watch b{display:block;color:var(--on-tint);font-size:15px;letter-spacing:-.02em;margin-bottom:8px}
.watch p{margin:0;font-size:15.5px;line-height:1.65}
.watch p+p{margin-top:13px}
.watch a{color:var(--on-tint);font-weight:700}

/* The tracked-user curve. An inline SVG rather than an image, so it themes
   with the page and stays sharp; the figures are in the post's table too, so
   the chart is the illustration and never the only place a number appears. */
.article .curve{margin:30px 0;padding:20px 18px 14px;border-radius:18px;
  background:var(--sunk)}
.article .curve svg{display:block;width:100%;height:auto;overflow:visible}
.article .curve .cv-ax{font-size:11.5px;fill:var(--muted);
  font-variant-numeric:tabular-nums}
.article .curve .cv-lb{font-size:12.5px;font-weight:600}
.article .curve figcaption{margin-top:12px;font-size:13.5px;line-height:1.55;
  color:var(--muted);text-wrap:pretty}
/* The second legend entry sits beside the first on a wide screen and wraps
   under it on a phone, where there is no room for both on one line. Both
   offsets live here rather than in the SVG so one asset serves both. */
.article .curve .cv-leg2{transform:translateX(150px)}
/* SVG text scales with the viewBox, so on a phone the sizes have to go UP in
   user units to survive the downscale, not down. At 375px the box renders at
   about 0.44 of its 720 units, so 22 units reads as roughly 10px. Six x labels
   will not fit legibly at that size, so alternate ones drop out, and the
   second legend entry wraps under the first. */
@media (max-width:560px){
  .article .curve{padding:14px 10px 10px}
  .article .curve .cv-ax{font-size:21px}
  .article .curve .cv-lb{font-size:23px}
  .article .curve .cv-alt{display:none}
  .article .curve .cv-leg2{transform:translateY(36px)}
}

/* Unpublished drafts. These carry noindex and are kept out of the index and
   the sitemap, because a page that invents first-hand experience would fail
   the one test that matters for both search and AI citation: whether the
   specifics are real. The styling is deliberately loud so a gap cannot be
   mistaken for finished copy at a glance. */
.article .draftbar{margin:0 0 26px;padding:14px 18px;border-radius:14px;
  background:var(--tint);color:var(--on-tint);font-size:14.5px;line-height:1.55}
.article .draftbar b{color:var(--on-tint)}
.article p.todo{margin:22px 0;padding:14px 16px;border-radius:12px;
  background:var(--wash);color:var(--ink);font-size:14.5px;line-height:1.6}
.article p.todo::before{content:"NEEDS REAL DETAIL";display:block;
  font-size:11px;letter-spacing:.08em;font-weight:700;color:var(--accent);
  margin-bottom:6px}
.article mark.todo-in{background:var(--wash);color:var(--ink);
  padding:1px 6px;border-radius:6px;font-style:italic}

/* A sourced quotation. Distinct from .note, which is our own aside: this one
   is somebody else's words, so it is a real blockquote with a real cite and
   it names where it came from. Separated by space and a type change rather
   than a rule or a side stripe. */
.article blockquote.pull{
  margin:2.25rem 0;padding:0;
}
.article blockquote.pull p{
  margin:0;font-size:1.18em;line-height:1.45;letter-spacing:-.015em;
  color:var(--ink);text-wrap:pretty;
}
.article blockquote.pull cite{
  display:block;margin-top:.75rem;font-style:normal;
  font-size:.85em;color:var(--muted);
}
.article blockquote.pull cite a{color:var(--accent)}

/* ============================================================
   PHONES

   Everything here is a phone-only correction to a rule written for
   a wide screen. It is at the FOOT of the file on purpose: several
   of these override selectors of equal specificity, and at equal
   specificity the later rule wins whatever the media query says.

   Measured at 375 (the common iPhone width) and 320 (SE first gen,
   still the realistic floor), with the entry animations frozen so
   nothing is read mid-flight.
   ============================================================ */

/* A long unbroken token inside inline code is the one thing on an
   article page that can take the whole document past the viewport:
   an OAuth redirect_uri and a Google app-password URL each did, at
   609px and 336px against a 320 viewport. `pre` has its own
   scroller and is deliberately left alone; this is for the inline
   spans sitting inside a paragraph, which have nowhere to scroll. */
.article code{overflow-wrap:anywhere}

/* The section head is a baseline row of title + subtitle. Below 560
   both halves wrap and the two ragged blocks read as one confused
   paragraph, so the subtitle takes its own line and the title gets
   the full measure. `.more` stays on the title's row, where its
   margin-left:auto still puts it hard right. */
@media (max-width:560px){
  .sect-h{flex-wrap:wrap;gap:6px 16px}
  .sect-h p{flex:1 0 100%}
}

/* Two large buttons side by side in the mid-article call to action
   need 358px at 320 and take the page with them. They wrap into a
   column and each takes the full width, which is the ordinary
   phone treatment for a pair of primary actions anyway. */
@media (max-width:560px){
  .midcta{flex-direction:column;align-items:stretch}
  /* flex:1 1 220px on the text block is a WIDTH while the row is a row
     and a HEIGHT the moment it becomes a column, so a three-line box
     stood 220px tall with 200 of them empty. */
  .midcta>div{flex:0 0 auto}
  .midcta .paths{margin-left:0;display:grid;grid-template-columns:1fr;gap:10px;width:100%}
  .midcta .paths .btn{width:100%}
}

/* The legal contents list is a stack of touching links at 30px a
   row. That clears the WCAG minimum and is still tighter than a
   thumb wants when the next target starts immediately underneath,
   so the rows go to 36. Only on the single-column layout: in two
   columns the extra height doubles into the page. */
@media (max-width:620px){
  .article .toc a{padding:8px 0}
}

/* A heading is the one place a single unbreakable token can take the whole
   document sideways, because it is the largest type on the page and it has
   no scroller to fall back on. Two troubleshooting posts are titled after
   the error string they are about: "ERR_TOO_MANY_REDIRECTS" sets 427px wide
   at 30px against a 320 viewport, and "redirect_uri_mismatch" 326.
   break-word, not anywhere: it only breaks a word that could not fit on a
   line of its own, so every ordinary title still wraps between words. */
h1,h2,h3,h4,.article code{overflow-wrap:break-word}

/* ---- Tap targets on a phone ----

   Probed, not measured off the box: several controls on this site are
   already enlarged by a stretched pseudo-element and reporting their
   boxes would send you "fixing" what is right. These four came back the
   size they look, with a thumb-sized area nowhere near them.

   Every expansion is a pseudo-element rather than padding, so nothing
   moves: the diff is a hit area, not a layout. And each was checked
   against its neighbour, because two overlapping hit areas is a worse
   bug than a small one.

   Only on touch widths. Expanding these on a desktop, where a pointer
   is pixel-accurate, buys nothing and risks reaching a neighbour. */
@media (max-width:820px){
  /* The wordmark, in the bar and in the footer: 25px and 22px tall,
     with the nearest thing to it 22px away in the bar and a paragraph
     in the footer. */
  .brand{position:relative}
  .brand::after{content:"";position:absolute;inset:-10px -8px}

  /* "Blog" and "Compare" in the bar, 21px tall. Not .btn: the button
     beside them is already 36 and growing both would close the 22px
     gap between them to two. */
  #hd nav a:not(.btn){position:relative}
  #hd nav a:not(.btn)::after{content:"";position:absolute;inset:-9px -5px}

  /* "All articles", top right of a section head. */
  .sect-h .more{position:relative}
  .sect-h .more::after{content:"";position:absolute;inset:-12px -8px}

  /* The FAQ question. The 16px of air above and below it belongs to the
     <details> around it, and clicking a details' own padding does not
     toggle anything, so a 54px-tall head had a 22px control in it. The
     pseudo-element claims exactly that padding and nothing further, so
     the answer below an open one is untouched. ::before, because
     ::after is already the chevron. */
  .faq summary{position:relative}
  .faq summary::before{content:"";position:absolute;top:-16px;right:-20px;bottom:-16px;left:-20px}
}
