/* Patent Case Watch — styles */

:root {
  --paper: #fafaf7;
  --card: #ffffff;
  --ink: #1c2128;
  --ink-soft: #4b5563;
  /* Darkened from #8a919c, which was 3.18:1 on --card, 3.04:1 on --paper and
   * 2.78:1 on --neutral-bg, against the 4.5:1 that WCAG 1.4.3 requires for text
   * this size. It carried eleven components -- metadata rows, filter labels,
   * the result count, breadcrumbs, definition-list terms, the footer -- so one
   * token accounted for eleven of the thirteen contrast failures on the site.
   * Hue and saturation are unchanged (216.7deg -> 217.9deg); only lightness
   * moved, so the grey still reads as the same cool grey. Now 5.29 / 5.06 /
   * 4.63:1 on those three backgrounds, and still clearly lighter than
   * --ink-soft, which is what keeps the three-step text hierarchy legible. */
  --ink-faint: #656c78;
  --line: #e5e4df;
  --navy: #1f3a5f;
  --navy-dark: #16293f;
  --edtx: #8c2f39;      /* deep brick — E.D. Tex. */
  --edtx-bg: #f7ecec;
  --cafc: #1f3a5f;      /* federal navy — Fed. Cir. */
  --cafc-bg: #eaeff5;
  --granted: #1e6f43;
  --granted-bg: #e7f2ea;
  --denied: #9b2c2c;
  --denied-bg: #f9ebeb;
  /* Darkened from #8a6d1a (4.34:1 on --mixed-bg) -- a marginal 1.4.3 miss, and
   * the only holding chip that failed. Taken to 5.05:1 rather than the bare
   * 4.5:1 so the four chips sit in the same band: granted 5.36, denied 6.49,
   * neutral 6.62. Hue is untouched (44.5deg -> 44.4deg), so it is still the
   * same ochre. */
  --mixed: #7e6318;
  --mixed-bg: #f7f1de;
  --neutral: #4b5563;
  --neutral-bg: #eef0f2;
  --serif: "Iowan Old Style", "Palatino", "Palatino Linotype", Georgia, "Times New Roman", serif;
  --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Arial, sans-serif;
}

* { box-sizing: border-box; margin: 0; padding: 0; }

html { -webkit-text-size-adjust: 100%; }

body {
  font-family: var(--sans);
  background: var(--paper);
  color: var(--ink);
  line-height: 1.55;
  font-size: 15.5px;
}

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

/* WCAG 1.4.1 Use of Colour (Level A). A link inside running prose was
 * distinguished from the text around it by colour alone: navy #1f3a5f against
 * ink #1c2128 is 1.41:1, where the criterion wants 3:1. Underlining is the
 * only fix that does not require repainting either colour.
 *
 * Scoped to `p a` because that is exactly what axe-core's link-in-text-block
 * rule flagged, on every page it flagged anything: the contact link, the
 * corrections address, and the govinfo link in the footer sentence. Links that
 * already carry a non-colour affordance are deliberately untouched -- the
 * masthead wordmark, card titles, tag ribbons, the PDF button, and the year-nav
 * chips are all shapes or headings, not words in a sentence.
 *
 * Breadcrumbs are included for a different reason: every crumb is --ink-faint,
 * so the linked crumbs and the current-page crumb were the same colour as each
 * other. There was no visual cue at all, which is worse than a weak one. */
p a,
.breadcrumb a { text-decoration: underline; text-underline-offset: 2px; }

.wrap { max-width: 880px; margin: 0 auto; padding: 0 24px; }

/* ---------- Masthead ---------- */

.masthead {
  background: var(--navy-dark);
  color: #fff;
  border-bottom: 3px solid var(--edtx);
}

.masthead .wrap {
  padding-top: 34px;
  padding-bottom: 30px;
}

.brand {
  font-family: var(--serif);
  font-size: 30px;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: #fff;
  /* index.html carries the wordmark as <h1>; every other page uses a <div> and
   * spends its <h1> on the page title. Zeroing the margin means the element can
   * be either without the browser's default h1 margin moving the masthead. */
  margin: 0;
}
.brand a { color: #fff; }
.brand a:hover { text-decoration: none; }

.brand .amp { color: #c8a24a; font-style: italic; }

.tagline {
  margin-top: 6px;
  font-size: 13.5px;
  color: #b9c4d2;
  letter-spacing: 0.02em;
}

/* ---------- Filter bar ---------- */

/* Hidden by default, because every control inside is built by JavaScript: a
 * no-JS visitor would otherwise get four labels, two empty dropdowns and a
 * search box that accepts typing and does nothing.
 *
 * The reveal has to happen in CSS, not JavaScript. It was previously the
 * hidden attribute cleared in app.js init(), which meant the browser painted
 * the page with no filter bar and then app.js inserted ~300px above the feed:
 * Lighthouse measured CLS 0.292 on mobile, and an A/B against an
 * otherwise-identical page put 0.217 of that on this one element. (The
 * commit that introduced it claimed CLS 0 in good faith -- the headless
 * browser it was measured in never painted, so it recorded no shifts at all.
 * CLS cannot be measured anywhere that does not paint.)
 *
 * `scripting: enabled` is evaluated while the stylesheet is parsed, before
 * anything is painted, so the bar is present and correctly sized in the first
 * frame. No inline <style> (blocked by style-src 'self'), no head script, no
 * extra request. app.js keeps a display fallback for browsers that do not
 * support the media feature -- those still get a working filter bar, just
 * with the shift this removes everywhere else. */
.filters {
  display: none;
  background: var(--card);
  border-bottom: 1px solid var(--line);
  box-shadow: 0 1px 2px rgba(20, 25, 35, 0.04);
}

@media (scripting: enabled) {
  .filters { display: block; }
}

.filters .wrap {
  padding-top: 14px;
  padding-bottom: 14px;
  display: flex;
  flex-wrap: wrap;
  gap: 10px 28px;
  align-items: flex-start;
}

.filter-group { min-width: 0; }

.filter-label {
  font-size: 10.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--ink-faint);
  margin-bottom: 6px;
}

/* min-height reserves one row of pills. The container ships empty -- app.js
 * builds the venue buttons -- so without this it is 0px tall in the first
 * frame and then jumps to a full row, pushing the entire feed down. That was
 * the whole of the residual CLS after the filter bar itself stopped being
 * revealed by script: measured at 85px of downward movement, and it is the
 * only control that does it (both <select>s keep their height while empty).
 * 25px is one pill: 12.5px text, 4px padding top and bottom, 1px borders. */
.pills { display: flex; flex-wrap: wrap; gap: 6px; min-height: 25px; }

.pill {
  font-family: var(--sans);
  font-size: 12.5px;
  padding: 4px 11px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--paper);
  color: var(--ink-soft);
  cursor: pointer;
  transition: all 0.12s ease;
  white-space: nowrap;
}

.pill:hover { border-color: var(--navy); color: var(--navy); }

.pill.active {
  background: var(--navy);
  border-color: var(--navy);
  color: #fff;
}

.search-input {
  font-family: var(--sans);
  font-size: 13px;
  padding: 5px 12px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--paper);
  color: var(--ink);
  width: 190px;
  outline: none;
  transition: border-color 0.12s ease;
}
.search-input:focus { border-color: var(--navy); }
.search-input::placeholder { color: var(--ink-faint); }

.year-select,
.filter-select {
  font-family: var(--sans);
  font-size: 12.5px;
  padding: 4px 10px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--paper);
  color: var(--ink-soft);
  outline: none;
}
.year-select:focus,
.filter-select:focus { border-color: var(--navy); }

.filter-select {
  width: 190px;
  max-width: 190px;
}

.load-more {
  display: block;
  width: 100%;
  font-family: var(--sans);
  font-size: 14px;
  font-weight: 600;
  color: var(--navy);
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 12px;
  cursor: pointer;
  margin: 4px 0 24px;
  transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.load-more:hover { border-color: var(--navy); box-shadow: 0 2px 8px rgba(20,25,35,0.06); }

.meta-note { color: var(--ink-faint); font-size: 12px; }

.auto-note {
  font-size: 12.5px;
  color: var(--ink-faint);
  background: var(--neutral-bg);
  border-left: 3px solid var(--line);
  padding: 8px 12px;
  border-radius: 0 4px 4px 0;
  margin-bottom: 14px;
}

.filter-meta {
  margin-left: auto;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 6px;
}

/* No white-space: nowrap here. "Showing 100 of 4,580 opinions - newest decision
 * first" cannot fit on one line at 320px, and forcing it produced 18px of
 * horizontal page overflow -- a WCAG 1.4.10 Reflow failure, which also covers
 * 400% zoom on a 1280px screen. Removing nowrap takes the overflow to exactly
 * 0; the count simply wraps to a second line on narrow screens. */
.result-count { font-size: 12.5px; color: var(--ink-faint); padding-top: 2px; }

.clear-btn {
  font-size: 12.5px;
  color: var(--edtx);
  background: none;
  border: none;
  cursor: pointer;
  /* Vertical padding to clear the 24px minimum tap target (WCAG 2.5.8). This
     is the only standalone control on the page that missed it, and on a phone
     it sits right under the result count where a near-miss hits nothing. The
     padding only counts because the visible state below is inline-BLOCK; on a
     plain inline box, vertical padding does not affect the line box at all. */
  padding: 5px 0;
  text-decoration: underline;
  display: none;
}
.clear-btn.visible { display: inline-block; }


/* ---------- Feed ---------- */

.feed .wrap { padding-top: 28px; padding-bottom: 60px; }

.feed-item {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 20px 24px 18px;
  margin-bottom: 14px;
  transition: box-shadow 0.15s ease, border-color 0.15s ease;
}

.feed-item:hover {
  border-color: #c9ccd2;
  box-shadow: 0 3px 12px rgba(20, 25, 35, 0.07);
}

.item-meta {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 8px;
  flex-wrap: wrap;
}

.venue-badge {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  padding: 3px 9px;
  border-radius: 4px;
}
.venue-badge.edtx { color: var(--edtx); background: var(--edtx-bg); }
.venue-badge.cafc { color: var(--cafc); background: var(--cafc-bg); }

.item-date, .item-type { font-size: 12.5px; color: var(--ink-faint); }
/* .item-meta is a wrapping flex row, so this separator belongs to the item that
   follows it and travels with it onto the next line — leaving an orphaned "·"
   at the start of that line. It only ever wraps on narrow screens, where the
   line break already separates the two values, so the dot is dropped there
   rather than dragged along. */
.item-type::before { content: "·"; margin-right: 10px; }
@media (max-width: 640px) {
  .item-type::before { content: none; }
}

.item-title {
  font-family: var(--serif);
  font-size: 19px;
  font-weight: 600;
  line-height: 1.35;
  margin-bottom: 8px;
}
.item-title a { color: var(--ink); }
.item-title a:hover { color: var(--navy); }

.item-teaser {
  font-size: 14px;
  color: var(--ink-soft);
  margin-bottom: 12px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  /* Teasers are not in feed-index.js; they arrive later from the per-year
     snippet shard. Reserve the two clamped lines up front so the cards do not
     render short and then push everything below them down when the shard
     lands — measured at a 4,340 px jump for a 100-card page. 2 x 1.55
     (the inherited line-height) = the exact height of the clamped block. */
  min-height: 3.1em;
}

/* Shown in place of a card excerpt when that year's snippet shard could not
 * be loaded. Must come after .item-teaser: both are single-class selectors,
 * so specificity ties and source order is what decides the colour.
 * Deliberately distinguished from real excerpt text -- an excerpt is the
 * court's own words, and a failure notice in the same voice would be
 * indistinguishable from one. Keeps the reserved two-line height, so a
 * failed shard still causes no layout shift. */
.item-teaser-unavailable { color: var(--ink-faint); font-style: italic; }

.item-foot {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
}

.tag {
  font-size: 11.5px;
  color: var(--ink-soft);
  background: var(--neutral-bg);
  padding: 3px 10px;
  border-radius: 4px;
}

.holding-chip {
  font-size: 11.5px;
  font-weight: 700;
  padding: 3px 10px;
  border-radius: 4px;
  margin-left: auto;
  white-space: nowrap;
}
.holding-granted   { color: var(--granted); background: var(--granted-bg); }
.holding-denied    { color: var(--denied);  background: var(--denied-bg); }
.holding-mixed     { color: var(--mixed);   background: var(--mixed-bg); }
.holding-neutral   { color: var(--neutral); background: var(--neutral-bg); }

.empty-state {
  text-align: center;
  color: var(--ink-faint);
  padding: 60px 0;
  font-size: 15px;
}

/* ---------- Detail page ---------- */

.breadcrumb {
  padding-top: 26px;
  font-size: 13px;
  color: var(--ink-faint);
}
.breadcrumb a { color: var(--ink-faint); }
.breadcrumb a:hover { color: var(--navy); }

.opinion-head { padding-top: 14px; padding-bottom: 4px; }

.opinion-title {
  font-family: var(--serif);
  font-size: 27px;
  font-weight: 600;
  line-height: 1.3;
  margin: 10px 0 18px;
}

.opinion-meta {
  display: grid;
  grid-template-columns: 130px 1fr;
  gap: 7px 16px;
  font-size: 13.5px;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 18px 22px;
  margin-bottom: 20px;
}
.opinion-meta dt {
  font-weight: 700;
  color: var(--ink-faint);
  text-transform: uppercase;
  font-size: 10.5px;
  letter-spacing: 0.08em;
  padding-top: 2px;
}
.opinion-meta dd { color: var(--ink); }

.ribbons { display: flex; flex-wrap: wrap; gap: 7px; margin-bottom: 22px; }

.ribbon {
  font-size: 12px;
  font-weight: 600;
  color: var(--navy);
  background: var(--cafc-bg);
  border-left: 3px solid var(--navy);
  padding: 5px 12px;
  border-radius: 0 4px 4px 0;
}

.holding-banner {
  display: inline-flex;
  align-items: baseline;
  gap: 10px;
  font-size: 14px;
  padding: 10px 16px;
  border-radius: 6px;
  margin-bottom: 26px;
}
.holding-banner .label { font-weight: 800; text-transform: uppercase; font-size: 12px; letter-spacing: 0.05em; }

.pdf-btn {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  background: var(--navy);
  color: #fff;
  font-size: 14px;
  font-weight: 600;
  padding: 10px 18px;
  border-radius: 6px;
  margin-bottom: 8px;
  transition: background 0.12s ease;
}
.pdf-btn:hover { background: var(--navy-dark); text-decoration: none; }
.pdf-btn svg { flex-shrink: 0; }

.source-link { font-size: 12.5px; color: var(--ink-faint); margin-bottom: 30px; }

.summary-section h2 {
  font-family: var(--serif);
  font-size: 17px;
  font-weight: 600;
  border-bottom: 1px solid var(--line);
  padding-bottom: 8px;
  margin-bottom: 14px;
}

.summary-section p {
  font-size: 15px;
  color: #2a3038;
  margin-bottom: 14px;
  line-height: 1.7;
}

.opinion-body { padding-bottom: 70px; }

.actions { margin: 26px 0 6px; }

/* ---------- Static archive & opinion pages ---------- */

.archive-body { padding-bottom: 70px; }

.archive-title {
  font-family: var(--serif);
  font-size: 26px;
  font-weight: 600;
  margin: 18px 0 6px;
}

.archive-intro { font-size: 14px; color: var(--ink-soft); margin-bottom: 22px; }

.archive-month {
  font-family: var(--serif);
  font-size: 17px;
  font-weight: 600;
  border-bottom: 1px solid var(--line);
  padding-bottom: 6px;
  margin: 26px 0 10px;
}

.archive-list { list-style: none; }
.archive-list li {
  padding: 7px 0;
  border-bottom: 1px solid var(--line);
  font-size: 14px;
  display: flex;
  gap: 10px;
  align-items: baseline;
  flex-wrap: wrap;
}
.archive-list .item-date { flex-shrink: 0; min-width: 88px; }

.year-nav { display: flex; flex-wrap: wrap; gap: 8px; margin: 16px 0 30px; }
.year-nav a {
  font-size: 13.5px;
  padding: 5px 13px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--card);
  color: var(--navy);
}
.year-nav a:hover { border-color: var(--navy); text-decoration: none; }

.related-docs { margin-top: 34px; }
.related-docs h2 {
  font-family: var(--serif);
  font-size: 17px;
  font-weight: 600;
  border-bottom: 1px solid var(--line);
  padding-bottom: 8px;
  margin-bottom: 10px;
}
.related-docs ul { list-style: none; }
.related-docs li { padding: 6px 0; font-size: 14px; display: flex; gap: 10px; flex-wrap: wrap; align-items: baseline; }
.related-docs .item-date { flex-shrink: 0; min-width: 88px; }

.footer-nav { margin-bottom: 12px; font-size: 13.5px; }

/* ---------- Accessibility ---------- */

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background: var(--navy-dark);
  color: #fff;
  padding: 10px 18px;
  border-radius: 0 0 6px 0;
  font-size: 14px;
}
.skip-link:focus {
  left: 0;
  text-decoration: none;
  outline: 2px solid #c8a24a;
}

.pill:focus-visible,
.filter-select:focus-visible,
.year-select:focus-visible,
.search-input:focus-visible,
.load-more:focus-visible,
.clear-btn:focus-visible,
a:focus-visible {
  outline: 2px solid var(--navy);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

.unavailable-note {
  font-size: 14px;
  color: var(--ink);
  background: var(--denied-bg);
  border-left: 3px solid var(--denied);
  padding: 12px 16px;
  border-radius: 0 6px 6px 0;
  margin: 26px 0 8px;
  max-width: 640px;
}

a.ribbon:hover { text-decoration: none; border-left-color: var(--edtx); }

.noscript-note {
  font-size: 14px;
  color: var(--ink-soft);
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 12px 16px;
  margin-bottom: 16px;
}

/* ---------- Advertising ---------- */

.ad-slot {
  display: block;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--card);
  padding: 10px 12px 12px;
  text-align: center;
  overflow: hidden;
}

.ad-label {
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--ink-faint);
  text-align: left;
  margin-bottom: 8px;
}

.ad-placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--ink-faint);
  font-size: 13px;
  background: repeating-linear-gradient(45deg, var(--paper), var(--paper) 10px, #f2f1ec 10px, #f2f1ec 20px);
  border: 1px dashed var(--line);
  border-radius: 6px;
}

/* In-feed unit: sits between feed cards, matched to their rhythm. */
.ad-feed { margin-bottom: 14px; }
.ad-feed .ad-placeholder { min-height: 96px; }
.ad-feed .adsbygoogle { display: block; min-height: 96px; }

/* Side rail on opinion detail pages. */
.opinion-layout { display: block; }
.ad-side { margin-top: 24px; }
.ad-side .ad-placeholder { min-height: 250px; }
.ad-side .adsbygoogle { display: block; min-height: 250px; }

@media (min-width: 940px) {
  /* widen the opinion page so the 300px rail doesn't squeeze the text */
  .wrap.opinion-body { max-width: 1040px; }
  .opinion-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 300px;
    gap: 40px;
    align-items: start;
  }
  .ad-side {
    margin-top: 0;
    position: sticky;
    top: 20px;
  }
  .ad-side .ad-placeholder { min-height: 600px; }
  .ad-side .adsbygoogle { min-height: 600px; }
}

/* ---------- Footer ---------- */

.site-footer {
  border-top: 1px solid var(--line);
  background: var(--card);
}
.site-footer .wrap {
  padding-top: 22px;
  padding-bottom: 30px;
  font-size: 12.5px;
  color: var(--ink-faint);
  line-height: 1.7;
}

/* ---------- Responsive ---------- */

@media (max-width: 640px) {
  .filters .wrap { gap: 12px; }
  .filter-meta { margin-left: 0; align-items: flex-start; }
  .holding-chip { margin-left: 0; }
  .opinion-meta { grid-template-columns: 1fr; gap: 2px; }
  .opinion-meta dt { margin-top: 10px; }
  .opinion-title { font-size: 22px; }
  .brand { font-size: 24px; }
}

/* ---------- Digest signup (Phase 1) ---------- */
/* Rendered only when apiOrigin is configured; see subscribe_form_html() in
   pipeline/gen_data_full.py. Two placements share these styles: a full-width
   band under the masthead on the feed, and a quieter block at the foot of each
   opinion page. */

.subscribe {
  background: var(--card);
  border-bottom: 1px solid var(--line);
  padding: 22px 0 24px;
}
.subscribe-doc {
  border: 1px solid var(--line);
  border-left: 3px solid var(--navy);
  background: var(--paper);
  margin: 32px 0 8px;
  padding: 18px 0 20px;
}
.subscribe-doc .wrap { padding: 0 20px; max-width: none; }

.subscribe-h {
  font-family: var(--serif);
  font-size: 1.22rem;
  margin: 0 0 4px;
  color: var(--ink);
}
.subscribe-doc .subscribe-h { font-size: 1.08rem; }

.subscribe-blurb {
  margin: 0 0 12px;
  font-size: 0.9rem;
  color: var(--ink-soft);
  max-width: 62ch;
}

.subscribe-form {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}
/* The visible label is redundant next to the placeholder for sighted users but
   is what screen readers announce; keep it in the accessibility tree only. */
.subscribe-label {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}
.subscribe-input {
  flex: 1 1 240px;
  min-width: 0;
  font-family: var(--sans);
  font-size: 0.95rem;
  padding: 9px 11px;
  border: 1px solid var(--line);
  border-radius: 3px;
  background: #fff;
  color: var(--ink);
}
.subscribe-input:focus {
  outline: 2px solid var(--navy);
  outline-offset: 1px;
  border-color: var(--navy);
}
.subscribe-input:disabled { background: var(--neutral-bg); color: var(--ink-faint); }

.subscribe-btn {
  flex: 0 0 auto;
  font-family: var(--sans);
  font-size: 0.9rem;
  font-weight: 600;
  padding: 10px 18px;
  border: 1px solid var(--navy-dark);
  border-radius: 3px;
  background: var(--navy);
  color: #fff;
  cursor: pointer;
}
.subscribe-btn:hover:not(:disabled) { background: var(--navy-dark); }
.subscribe-btn:disabled { opacity: 0.55; cursor: default; }

/* The honeypot must be unreachable for people — including keyboard and screen
   reader users — while staying a real, fillable field for a scripted client.
   Hence off-canvas rather than display:none, which some bots detect. */
.subscribe-hp {
  position: absolute;
  left: -9999px;
  top: auto;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.subscribe-note {
  flex: 1 1 100%;
  margin: 2px 0 0;
  font-size: 0.76rem;
  color: var(--ink-faint);
}
.subscribe-status {
  flex: 1 1 100%;
  margin: 0;
  font-size: 0.85rem;
}
.subscribe-status:empty { display: none; }
.subscribe-status.is-ok { color: var(--granted); font-weight: 600; }
.subscribe-status.is-error { color: var(--denied); font-weight: 600; }

@media (max-width: 560px) {
  .subscribe-form { gap: 8px; }
  .subscribe-input, .subscribe-btn { flex: 1 1 100%; }
}
