/* ══════════════════════════════════════════════════════════════════════════
   WATCHLIST — /watchlist.html

   Ported from the reference dashboard's second Watchlist design (the one that
   renders: six alert groups on top, what is followed on the left, the feed on the
   right). The port is close to declaration-for-declaration so a future version of
   the reference stays diffable against this file.

   TWO THINGS ARE DELIBERATELY DIFFERENT.

   1. NO COLOUR IS WRITTEN HERE. The reference ships its own :root hex block; that
      would fight css/app.css, which keys eight complete palette blocks on the
      data-palette + data-theme pair. Every colour below is a var() that
      css/app-sidebar.css's `#app-shell` alias block maps onto the live palette
      (--ink/--card/--sunk2/--rule/--up/--dn/--amber/--blue), so all four palettes
      in both modes drive this page for free. That alias block is also why the page
      is wrapped in <div id="app-shell"> at all.

   2. EVERY RULE IS SCOPED. The reference styles .chead, .chl, .card, .lb, .sig,
      img.fl and .fpair once, globally. In this codebase those names exist only
      inside OTHER views' stylesheets (#view-pairs .chead, #view-currencies .fpair,
      …), none of which this document links and none of which would match
      #view-watchlist anyway. So the ones this page needs are restated here, under
      #view-watchlist, rather than borrowed.

   Fonts: "IBM Plex Mono" is not available locally. It is mapped ONCE onto the
   self-hosted mono stack through var(--fmono); no rule below names a family.
   ══════════════════════════════════════════════════════════════════════════ */

/* -- the page masthead ------------------------------------------------------ */

/* PORTED VERBATIM from css/data.css `.dmast` (which is the reference's §3.2), class
   names and all. The Data page and this one link to each other from inside these
   headers, and a reader crossing between them was watching the header change shape,
   change type size and change whether it stays pinned while scrolling — two documents
   shipped in one batch reading as two different products.

   The names are not renamed on the way over deliberately: the two files declare the
   same rules, neither page links the other's stylesheet, and if a future version of the
   reference lands, both stay diffable against it.

   The page's own title lives in `.chead h1`/`h2` below, on the documented scale, rather
   than as a large word in this strip. */
#app-shell .dmast {
  display: flex; align-items: center; gap: 18px; flex-wrap: wrap;
  padding: 14px 0 12px; margin-bottom: 4px;
  border-bottom: 1px solid var(--rule);
  position: sticky; top: 0; z-index: 30; background: var(--bg);
}
/* `margin: 0` is the ONE declaration this copy adds to the ported rule: the element is
   an <h1> here rather than the Data page's <span>, so the document has a top-level
   heading, and a browser's default h1 margin would push the strip open. */
#app-shell .dmast .wm {
  margin: 0;
  font-family: var(--fmono); font-size: 12px; font-weight: 600;
  letter-spacing: .16em; text-transform: uppercase; color: var(--soft);
}
#app-shell .dmast .stat {
  margin-left: auto; display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  justify-content: flex-end; font-family: var(--fmono); font-size: 11px; color: var(--faint);
}
#app-shell .dmast .stat .sep { width: 1px; height: 11px; background: var(--rule2); display: inline-block; }
#app-shell .dmast .stat .upd { color: var(--soft); }
#app-shell .dmast .mlink {
  display: inline-flex; align-items: center; gap: 6px; padding: 5px 11px;
  border: 1px solid var(--rule2); border-radius: 999px; background: var(--card);
  color: var(--soft); font-family: var(--fsans); font-size: 12px; text-decoration: none;
  white-space: nowrap;
}
#app-shell .dmast .mlink:hover { border-color: var(--ink); color: var(--ink); }
#app-shell .dmast .mlink:focus-visible,
#app-shell .dmast .thm:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
/* app-sidebar.css stretches `.thm` to the full rail width when the rail is
   collapsed. That rule is scoped to #app-shell and therefore also catches the copy
   in our masthead, where a full-width theme button would swallow the row. */
#app-shell .dmast .thm,
#app-shell.nav-collapsed .dmast .thm { margin-left: 0; width: auto; padding: 5px 10px; }

/* -- the view --------------------------------------------------------------- */

/* surface.css makes .view a flex column with a gap; this page carries the
   reference's own margins between its three blocks, and the two together double
   the spacing. */
#view-watchlist.wl2 { display: block; max-width: 1200px; }
/* The cap is the PAGE's, not the content section's. `.dmast` and the legend are siblings
   of `#view-watchlist` inside `.appmain`, so a max-width on the section alone left both
   running the full width of the gutter while every card stopped at 1200px: on a 1904px
   window the heading rule and the disclosure legend hung about 120px past everything they
   were framing. Same number in all three places, written once per element rather than
   moved onto `.appmain`, which the rail's own stylesheet owns. */
#app-shell .dmast,
#app-shell #g10-disclaimer { max-width: 1200px; }
#view-watchlist button { font: inherit; cursor: pointer; border: 0; background: none; color: inherit; }
#view-watchlist button:focus-visible,
#view-watchlist a:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }

/* -- shared classes the reference defines globally and this page needs -------- */

#view-watchlist .card { background: var(--card); border: 1px solid var(--rule); border-radius: 12px; }
#view-watchlist .lb {
  font-family: var(--fmono); font-size: 10px; font-weight: 600; letter-spacing: .14em;
  text-transform: uppercase;
}
#view-watchlist .mut { margin: 0; font-size: 13.5px; color: var(--faint); }
#view-watchlist .soft { color: var(--soft); }
#view-watchlist .dthbn { margin: 5px 0 0; font-size: 11px; line-height: 1.45; color: var(--faint); }
#view-watchlist .dthbn b { color: var(--ink); }

#view-watchlist .chead { border-bottom: 1px solid var(--rule); padding-bottom: 22px; margin-bottom: 26px; }
#view-watchlist .chl {
  margin: 16px 0 10px; font-size: 23px; line-height: 1.3; font-weight: 700;
  letter-spacing: -.015em; color: var(--ink); max-width: 34ch; text-wrap: pretty;
}
#view-watchlist .chl.pbhl { margin-top: 0; }     /* first thing in .chead — nothing above it */
#view-watchlist .wltitle { max-width: 42ch; }
/* The per-file as-of list. It lives here rather than in the masthead because there are
   four of them and they are four different moments; the strip above carries the newest
   one and names its file, so neither place can read as a single page-wide as-of. */
#view-watchlist .wlstamps { margin: 0 0 10px; max-width: 86ch; }

#view-watchlist .foot {
  margin-top: 44px; padding-top: 16px; border-top: 1px solid var(--rule2);
  font-family: var(--fmono); font-size: 10.5px; line-height: 1.75; color: var(--faint);
}
#view-watchlist .foot p { margin: 0 0 8px; }
#view-watchlist .foot p:last-child { margin-bottom: 0; }

/* Flags. The ring is a hairline token rather than the reference's two hardcoded
   rgba values, so it follows the palette instead of needing a dark-mode twin. */
#view-watchlist img.fl {
  border-radius: 999px; object-fit: cover; vertical-align: -3px;
  box-shadow: 0 0 0 1px rgba(var(--hairline-rgb), .85);
}
#view-watchlist .fpair {
  display: inline-flex; align-items: center; flex: 0 0 auto; margin-right: 3px; vertical-align: middle;
}
#view-watchlist .fpair img.fl {
  border: 2px solid var(--card); box-sizing: content-box; border-radius: 999px;
  vertical-align: middle; position: relative;
}
#view-watchlist .fpair img.fl:first-child { z-index: 2; }
/* The second flag slides left by 40% of the flag size, so the overlap scales with
   the px the caller asked for instead of being written once per size. */
#view-watchlist .fpair img.fl + img.fl { margin-left: calc(var(--fp) * -0.40); z-index: 1; }

/* .sig is declared for #app-shell in app-sidebar.css (up/dn/nt only, for the rail's
   currency drop-down). The two this page adds are the amber WARNING pill, which is
   never a market direction, and the fixed-width direction pill. */
#view-watchlist .sig.wn { background: var(--amber-bg); border-color: var(--amber); color: var(--amber); }
#view-watchlist .sig.dir { min-width: 88px; justify-content: center; letter-spacing: .1em; }

/* -- the heading block ------------------------------------------------------ */

#view-watchlist .wlsum { margin: 0; max-width: 72ch; font-size: 14.5px; line-height: 1.55; color: var(--ink); }
#view-watchlist .wlsum + .wlsum { margin-top: 6px; }
#view-watchlist .wlsum.soft { font-size: 13px; color: var(--soft); }
#view-watchlist .wlsum b { font-weight: 650; }

/* -- the tile row ----------------------------------------------------------- */

#view-watchlist .wlcats {
  display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 8px; margin: 0 0 22px;
}
#view-watchlist .wlcat {
  display: flex; flex-direction: column; justify-content: space-between; gap: 10px; min-width: 0;
  padding: 11px 12px 10px; border: 1px solid var(--rule); border-radius: 10px;
  background: var(--card); text-align: left;
}
#view-watchlist .wlcat:hover { border-color: var(--rule2); }
/* the doubled border IS the selected state — no fill, so the count stays readable */
#view-watchlist .wlcat[aria-selected="true"] { border-color: var(--ink); box-shadow: inset 0 0 0 1px var(--ink); }
#view-watchlist .wlcat .t {
  display: flex; align-items: flex-start; gap: 7px; font-size: 12.5px; font-weight: 600;
  line-height: 1.3; color: var(--ink);
}
#view-watchlist .wlcat .t .wlic { flex: 0 0 auto; color: var(--soft); }
#view-watchlist .wlcat .n {
  display: flex; align-items: baseline; gap: 7px; font-family: var(--fmono);
  font-size: 20px; font-weight: 600; line-height: 1; color: var(--ink);
  font-variant-numeric: tabular-nums;
}
#view-watchlist .wlcat .n i { font-style: normal; font-size: 11px; font-weight: 600; color: var(--blue); }
#view-watchlist .wlcat.zero .n { color: var(--faint); }
/* `.zero` is a measured zero; `.dark` is a category whose sources did not answer, and
   its tile prints an em dash. The two must not look the same — one is a fact about the
   desk, the other a fact about this visit. The dashed border is the visual difference. */
#view-watchlist .wlcat.dark { border-style: dashed; }
#view-watchlist .wlcat.dark .n { color: var(--faint); }
/* The gloss of the selected category, as permanent text. It used to live only in a
   title attribute, which a touch or keyboard reader can never reach. */
#view-watchlist .wlcattip { margin: -14px 0 22px; max-width: 80ch; }

/* -- the two columns -------------------------------------------------------- */

#view-watchlist .wl2body {
  display: grid; grid-template-columns: 272px minmax(0, 1fr); gap: 20px; align-items: start;
}
/* The offset MEASURES the masthead rather than guessing it.

   The strip above is sticky at top:0 and is 58px tall only while it fits on ONE line. Once
   the stamp and the cross-links wrap under the page word it measures 95px, and at the
   literal 62px this rule used to carry the follow-list then pinned itself 33px UNDERNEATH
   it — the "Everything you follow" row and its unread count were not merely covered:
   elementFromPoint returned the masthead, so the control could not be clicked either.

   The width at which it wraps moves with whatever stamp string the page is rendering that
   day, so a second literal would be wrong again on a different one. js/watchlist.js writes
   `--wl-mast-h` off a ResizeObserver on the strip itself. The two numbers here reproduce
   today's geometry exactly when it has not run or has nothing to measure yet: 58 is the
   one-line height and 4 the clearance the old literal left, so 58 + 4 is that same 62px.
   Measured wrapped: 95 + 4 = 99, the same 3.6px of clearance, and a hit test on the top
   row of the list now lands in the list. The 860px block puts both back to static
   together. */
#view-watchlist .wl2side {
  position: sticky; top: calc(var(--wl-mast-h, 58px) + 4px);
  display: grid; gap: 8px; min-width: 0;
}
#view-watchlist .wl2list { display: grid; gap: 2px; padding: 6px; }
#view-watchlist .wl2it {
  display: flex; align-items: center; gap: 9px; width: 100%; min-height: 38px; padding: 7px 9px;
  border-radius: 8px; text-align: left; color: var(--ink); min-width: 0;
}
#view-watchlist .wl2it:hover { background: var(--sunk2); }
#view-watchlist .wl2it[aria-pressed="true"] { background: var(--sunk2); box-shadow: inset 3px 0 0 var(--ink); }
#view-watchlist .wl2it b { font-family: var(--fmono); font-size: 13px; font-weight: 600; }
#view-watchlist .wl2it .all { font-size: 13px; font-weight: 600; }
#view-watchlist .wl2it .sig { margin-left: auto; transform: scale(.84); transform-origin: right center; }
#view-watchlist .wl2it .wlpd { margin-left: auto; }
#view-watchlist .wl2it .nw,
#view-watchlist .wl2it .nw0 {
  flex: 0 0 auto; min-width: 20px; margin-left: 6px; padding: 0 6px; border-radius: 999px;
  font-family: var(--fmono); font-size: 10px; font-weight: 600; line-height: 18px; text-align: center;
}
/* NOT `--dn`. That token is `--bear-dot`, a DOT colour: a desaturated terracotta in this
   app's palettes (#B0736A slate light, #9E6F5E warm, #CE7440 teal), not the deep red the
   reference block assumed. Near-white on it measures 3.83 / 4.06 / 3.39 : 1 — under the
   4.5:1 floor in three of the four light palettes, the default one included, on a 10px
   badge. `--bear-text` is the same family's TEXT weight and clears 4.5:1 against the card
   in all eight palette/mode pairs (6.2 : 1 at worst, 9.2 : 1 at best). */
#view-watchlist .wl2it .nw { background: var(--bear-text); color: var(--card); }
#view-watchlist .wl2it .all + .nw { margin-left: auto; }
#view-watchlist .wl2sep { height: 1px; margin: 4px 6px; background: var(--rule); }

/* -- the add picker --------------------------------------------------------- */

#view-watchlist .wl2add {
  display: flex; align-items: center; justify-content: center; gap: 6px; margin-top: 4px; padding: 8px;
  border: 1px dashed var(--rule2); border-radius: 8px; font-size: 12.5px; font-weight: 600;
  color: var(--soft); text-align: center;
}
#view-watchlist .wl2add:hover { border-color: var(--ink); color: var(--ink); }
#view-watchlist .wl2add[aria-expanded="true"] {
  border-style: solid; border-color: var(--ink); background: var(--ink); color: var(--bg);
}
#view-watchlist .wl2pick { display: grid; gap: 8px; padding: 10px 4px 4px; }
#view-watchlist .wl2pick > .lb { margin-top: 4px; color: var(--faint); }
#view-watchlist .wlcg { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6px; }
#view-watchlist .wlc,
#view-watchlist .wlp {
  display: flex; align-items: center; gap: 8px; padding: 6px 9px; border: 1px solid var(--rule2);
  border-radius: 8px; background: var(--card); min-width: 0;
}
#view-watchlist .wlc { font-family: var(--fmono); font-size: 12.5px; }
#view-watchlist .wlc:hover,
#view-watchlist .wlp:hover { border-color: var(--ink); }
#view-watchlist .wlc[aria-pressed="true"],
#view-watchlist .wlp[aria-pressed="true"] { border-color: var(--blue); background: var(--blue-bg); }
#view-watchlist .wlst { margin-left: auto; font-size: 13px; color: var(--faint); }
#view-watchlist .wlc[aria-pressed="true"] .wlst,
#view-watchlist .wlp[aria-pressed="true"] .wlst { color: var(--blue); }
/* Below 900px the rail becomes a full-width band and these ten sit on a phone. At the
   reference's 3px padding they were 27px square at a 30px pitch, and a mis-tap silently
   re-filters the pair list to the wrong currency. 6px takes them to 33px. */
#view-watchlist .wlpcs { display: flex; flex-wrap: wrap; gap: 6px; }
#view-watchlist .wlpc { padding: 6px; border: 1.5px solid transparent; border-radius: 999px; line-height: 0; }
#view-watchlist .wlpc:hover { border-color: var(--rule2); }
#view-watchlist .wlpc[aria-pressed="true"] { border-color: var(--ink); }
#view-watchlist .wlpl { display: grid; gap: 5px; }
#view-watchlist .wlp b { font-family: var(--fmono); font-size: 12.5px; font-weight: 600; }
#view-watchlist .wlpd { font-size: 11px; font-weight: 600; white-space: nowrap; }
#view-watchlist .wlpd.up { color: var(--up); }
#view-watchlist .wlpd.dn { color: var(--dn); }
#view-watchlist .wlpd.nt { color: var(--soft); }

/* -- the right column ------------------------------------------------------- */

#view-watchlist .wl2main { display: grid; gap: 24px; min-width: 0; }
#view-watchlist .wlitc { padding: 16px 18px; }
#view-watchlist .wlih { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 10px; }
#view-watchlist .wlnm { display: flex; flex-direction: column; margin-right: auto; line-height: 1.25; min-width: 0; }
#view-watchlist .wlnm b { font-family: var(--fmono); font-size: 15px; font-weight: 600; color: var(--ink); }
#view-watchlist .wlnm i { font-style: normal; font-size: 11.5px; color: var(--faint); }
#view-watchlist .wlrk { font-family: var(--fmono); font-size: 11.5px; color: var(--soft); white-space: nowrap; }
#view-watchlist .wlir {
  display: grid; align-content: start; gap: 9px; margin: 12px 0 10px; padding-top: 12px;
  border-top: 1px solid var(--rule);
}
#view-watchlist .wlir2 { margin-bottom: 12px; }
#view-watchlist .wlrw { display: grid; gap: 1px; min-width: 0; }
#view-watchlist .wlrw .lb { font-size: 9.5px; color: var(--faint); }
#view-watchlist .wlrw > span:last-child {
  font-size: 13px; line-height: 1.45; color: var(--ink); overflow-wrap: anywhere;
}
/* A price move, coloured by whether it went OUR way — not by its sign. Green is "the
   thing we are buying"; on a pair we are short of, a rise is red (REF_DESIGN_SYSTEM
   §5.3). Where there is no call to judge against, the number carries no colour at all
   rather than borrowing a meaning it has not earned. */
#view-watchlist .wlmv { font-variant-numeric: tabular-nums; }
#view-watchlist .wlmv.ok { color: var(--up); }
#view-watchlist .wlmv.no { color: var(--dn); }
#view-watchlist .wlmv.fl { color: var(--faint); }
#view-watchlist .wlset2 { display: grid; gap: 8px; padding: 12px 0; border-top: 1px solid var(--rule); }
#view-watchlist .wlset2 .lb { color: var(--faint); }
#view-watchlist .wltogs { display: flex; flex-wrap: wrap; gap: 6px; }
/* The LOUD state is "on". A muted category reads as crossed out, which is what the
   reader is actually choosing: the alerts they will not be shown. */
#view-watchlist .wltog {
  display: inline-flex; align-items: center; gap: 6px; padding: 5px 11px 5px 9px;
  border: 1px solid var(--rule2); border-radius: 999px; font-size: 12px; color: var(--faint);
  text-decoration: line-through; text-decoration-color: var(--rule2);
}
#view-watchlist .wltog:hover { border-color: var(--ink); }
#view-watchlist .wltog[aria-pressed="true"] {
  border-color: var(--blue); background: var(--blue-bg); color: var(--blue); text-decoration: none;
}
#view-watchlist .wlib {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; padding-top: 10px;
  border-top: 1px solid var(--rule);
}
/* A one-shot action on a 19px strip of bare text. The negative margin buys the target
   back without moving anything in the layout. */
#view-watchlist .wlun {
  padding: 6px 10px; margin: -6px -10px; font-size: 12px; font-weight: 600; color: var(--soft);
}
#view-watchlist .wlun:hover { color: var(--ink); }

/* -- the feeds -------------------------------------------------------------- */

#view-watchlist .wlfh { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 8px; }
#view-watchlist .wlfh h3 { margin: 0; font-size: 15px; font-weight: 650; color: var(--ink); }
#view-watchlist .wlfh h3 span { margin-left: 8px; font-family: var(--fmono); font-size: 12px; font-weight: 500; color: var(--faint); }
#view-watchlist .wlmark {
  flex: 0 0 auto; padding: 6px 10px; margin: -6px -10px;
  font-size: 12.5px; font-weight: 600; color: var(--blue);
}
#view-watchlist .wlmark:hover { text-decoration: underline; }
#view-watchlist .wlfeed { padding: 0; overflow: hidden; }   /* clips the row separators */

#view-watchlist .wlr {
  position: relative; display: grid; grid-template-columns: 32px minmax(0, 1fr) auto; gap: 14px;
  align-items: start; padding: 13px 18px; border-bottom: 1px solid var(--rule);
}
#view-watchlist .wlr:last-child { border-bottom: 0; }
#view-watchlist .wlr.new::before {
  content: ""; position: absolute; left: 6px; top: 24px; width: 6px; height: 6px;
  border-radius: 50%; background: var(--blue);
}
#view-watchlist .wlrc {
  display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px;
  border-radius: 8px; background: var(--sunk2); color: var(--soft);
}
/* the whole hot treatment: the icon chip goes red-on-red. There is no accent bar. */
#view-watchlist .wlr.hot .wlrc { background: var(--dn-bg); color: var(--dn); }
#view-watchlist .wlrb { min-width: 0; }
#view-watchlist .wlrm {
  display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; font-size: 11.5px; color: var(--faint);
}
#view-watchlist .wlrm img.fl,
#view-watchlist .wlrm .fpair { vertical-align: middle; }
#view-watchlist .wlrcat {
  font-family: var(--fmono); font-size: 10px; font-weight: 600; letter-spacing: .08em;
  text-transform: uppercase; color: var(--soft);
}
#view-watchlist .wlfor { font-size: 11px; font-weight: 500; letter-spacing: 0; text-transform: none; }
/* Same reason as `.nw` above: the fill is the bear TEXT weight, never the dot. This is
   the loudest chip on the page and it sits at 9.5px on the rows the page most wants
   read. */
#view-watchlist .wlhot {
  padding: 1px 6px; border-radius: 999px; background: var(--bear-text); color: var(--card);
  font-family: var(--fmono); font-size: 9.5px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase;
}
#view-watchlist .wlnew {
  padding: 1px 6px; border-radius: 999px; background: var(--blue); color: var(--card);
  font-size: 10px; font-weight: 600; letter-spacing: .06em;
}
#view-watchlist .wlrt {
  margin: 4px 0 0; font-size: 14px; font-weight: 600; line-height: 1.4; color: var(--ink);
  text-wrap: pretty; overflow-wrap: anywhere;
}
/* a read title lightens, it does not grey: it is still the thing you came to read */
#view-watchlist .wlr:not(.new) .wlrt { font-weight: 500; }
#view-watchlist .wlrs { margin: 3px 0 0; font-size: 12.5px; line-height: 1.5; color: var(--soft); overflow-wrap: anywhere; }
#view-watchlist .wlrr { display: flex; flex-direction: column; align-items: flex-end; gap: 8px; }
#view-watchlist .wlrtime { font-size: 11.5px; color: var(--faint); white-space: nowrap; font-variant-numeric: tabular-nums; }
/* A real link, not a button: the reader can middle-click it, and the row's only action is
   navigation. It is marked read on the way out. */
#view-watchlist .wlgo {
  display: inline-flex; align-items: center; gap: 6px; padding: 5px 11px; border-radius: 999px;
  background: var(--blue-bg); color: var(--blue); font-size: 12px; font-weight: 600;
  white-space: nowrap; text-decoration: none;
}
#view-watchlist .wlgo:hover { text-decoration: underline; }
#view-watchlist .wltags { display: inline-flex; flex-wrap: wrap; gap: 3px; margin-right: 6px; vertical-align: middle; }
#view-watchlist .nwtag {
  display: inline-flex; align-items: center; gap: 4px; padding: 1px 6px 1px 3px; border-radius: 999px;
  border: 1px solid var(--rule2); font-family: var(--fmono); font-size: 9.5px; font-weight: 600; color: var(--soft);
}
#view-watchlist .nwtag.up { border-color: var(--up-bd); color: var(--up); background: var(--up-bg); }
#view-watchlist .nwtag.dn { border-color: var(--dn-bd); color: var(--dn); background: var(--dn-bg); }
#view-watchlist .wlnone { margin: 0; font-size: 13px; }

/* -- what could not be read ------------------------------------------------- */

/* Its own block, above the feeds, because "we could not load it" and "there is
   nothing" must never render as the same thing. One line per source, in the
   reader's words, saying which of the three it is. */
#view-watchlist .wlmiss { padding: 12px 14px; display: grid; gap: 7px; }
#view-watchlist .wlmiss .lb { color: var(--faint); }
#view-watchlist .wlmiss ul { margin: 0; padding: 0; list-style: none; display: grid; gap: 5px; }
#view-watchlist .wlmiss li { font-size: 12.5px; line-height: 1.5; color: var(--soft); display: flex; gap: 8px; align-items: baseline; }
#view-watchlist .wlmiss .sig { flex: 0 0 auto; }

#view-watchlist .wlretry {
  margin-top: 2px; justify-self: start; padding: 5px 11px; border: 1px solid var(--rule2);
  border-radius: 999px; font-size: 12px; font-weight: 600; color: var(--soft);
}
#view-watchlist .wlretry:hover { border-color: var(--ink); color: var(--ink); }

/* -- responsive ------------------------------------------------------------- */

@media (max-width: 1180px) {
  #view-watchlist .wlcats { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
@media (max-width: 900px) {
  #view-watchlist .wl2body { grid-template-columns: minmax(0, 1fr); }
  #view-watchlist .wl2side { position: static; }
}
@media (max-width: 860px) {
  /* The masthead stops sticking here, exactly as the Data page's does. The rail stopped
     one breakpoint earlier, so nothing else needs undoing. */
  #app-shell .dmast { position: static; }
}
@media (max-width: 640px) {
  #view-watchlist .chl { font-size: 19px; }
}
@media (max-width: 560px) {
  #view-watchlist .wlcats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* the row's right-hand column drops under the body; the time and the go button
     then lay out side by side rather than stacking into a tall thin column */
  #view-watchlist .wlr { grid-template-columns: 28px minmax(0, 1fr); padding: 13px 14px; }
  /* WRAPPING IS NOT OPTIONAL HERE. Both children carry `white-space: nowrap`, so a flex
     row cannot shrink them below their min-content width; `space-between` degrades to
     flex-start once free space goes negative, and `.wlfeed { overflow: hidden }` then
     clips the tail of the row's only action. The stamps this page builds ("Tomorrow,
     Wed 16 Sep 12:30 UTC") and its go labels ("Open the Dashboard →") are far longer
     than the mock's, and the track at 360px is about 270px. */
  #view-watchlist .wlrr {
    grid-column: 2; flex-direction: row; align-items: center; flex-wrap: wrap;
    justify-content: space-between; row-gap: 6px; column-gap: 10px;
  }
  #app-shell .dmast { gap: 10px; }
  #app-shell .dmast .stat { margin-left: 0; justify-content: flex-start; }
}

/* -- print ------------------------------------------------------------------ */

/* Printing is a first-class output: everything interactive disappears and
   everything it was hiding stays. The feed is the content. */
@media print {
  #view-watchlist .wlcats,
  #view-watchlist .wl2side,
  #view-watchlist .wlgo,
  #view-watchlist .wlmark,
  #view-watchlist .wlretry,
  #app-shell .dmast .mlink,
  #app-shell .dmast .thm { display: none !important; }
  /* The tiles go, but what they were hiding does not: the selected category's meaning
     is the one line that explains the whole organising principle of the page. */
  #view-watchlist .wlcattip { margin-top: 0; }
  #app-shell .dmast { position: static; }
  #view-watchlist .wl2body { grid-template-columns: minmax(0, 1fr); }
  #view-watchlist .wlr { grid-template-columns: 28px minmax(0, 1fr); }
  #view-watchlist .wlrr { grid-column: 2; }
  #view-watchlist .card { box-shadow: none; }
}
