/* app-fixes.css — M53, from the live E2E of 2026-09-17. Loaded after app.css, so it only ADDS.
   The CSP is style-src 'self' with no 'unsafe-inline': an inline style="" attribute is dropped by
   the browser, silently. The command center was written with nine of them, so its tiles lost their
   grid, their severity border and their large count. Every rule here replaces something a view used to say inline or
   a class a view used that no stylesheet defined. */

/* ── command center ───────────────────────────────────────────────────────── */
.cc-title{margin:0 0 10px}
.tile-link{display:block;text-decoration:none;color:inherit;border-radius:18px}
.tile-link:focus-visible{outline:2px solid #151a21;outline-offset:2px}
.tiles .card.tile{margin:0;padding:12px;height:100%}
.tile .tile-kpi{font-size:22px;font-weight:700;line-height:1.3}
.tile strong{font-weight:700}
.tile .tile-next{font-weight:700;margin:4px 0}

/* ── checkboxes inside a .form ────────────────────────────────────────────────
   `.form input{width:100%}` stretched every checkbox across the card and put its label text on a
   separate line from the box it names. */
.form input[type=checkbox],.form input[type=radio],.auth input[type=checkbox]{width:auto;padding:0;margin:0;flex:0 0 auto}
.form label:has(> input[type=checkbox]),.form label:has(> input[type=radio]),.auth label:has(> input[type=checkbox]){display:flex;gap:8px;align-items:flex-start}

/* ── link bank ────────────────────────────────────────────────────────────── */
.linkbank h2{margin:0 0 12px;font-size:18px}
.linkbank h3{margin:18px 0 8px;font-size:15px}
.linkbank .hint{font-size:13px;margin:8px 0}
.lb-bar{grid-template-columns:repeat(auto-fit,minmax(180px,1fr));align-items:end}
.lb-row{display:grid;grid-template-columns:repeat(auto-fit,minmax(170px,1fr));gap:12px;align-items:end;margin-bottom:12px}
.lb-wide{grid-column:span 2}
.form textarea{width:100%;padding:11px 12px;border:1px solid #d9dfe7;border-radius:10px;background:#fff;font:inherit;resize:vertical}
.card.alert.error{border-right-color:#df4242;color:#a12727;font-weight:650}
.linkbank p.alert.error{border-right-color:#df4242;background:#fdeaea;color:#a12727;padding:10px 12px;border-radius:10px}
button.danger{background:#a12727}
.batch-actions .row{margin:12px 0}
.linkbank tr.open td{background:#f1f3f6}
.batch-rows tr.row-bad td{background:#fdeaea}
.batch-rows tr.row-dup td{background:#fff8e6}
.linkbank td.url{max-width:340px}
.linkbank td.url code{font-size:12px}
.linkbank td form.inline{display:flex;gap:6px;align-items:center}
.linkbank td select,.linkbank td input[name=integration_id]{padding:6px 8px;border:1px solid #d9dfe7;border-radius:8px;background:#fff;font:inherit;font-size:12px}
.linkbank td input[name=integration_id]{width:76px}
.linkbank .pager{margin-top:12px;flex-wrap:wrap}

/* ── wide-but-not-huge layout (N1) ────────────────────────────────────────────
   app.css collapses .tri (320px 320px 1fr) to one column only at <=1000px. Between 1001px and
   ~1350px the 245px sidebar leaves too little for two 320px columns plus the products table, and
   the `1fr` track (min-width:auto = the table's min-content) pushed the whole page sideways instead
   of scrolling inside its own .scroll-x. minmax(0,1fr) lets that track shrink so the table scrolls
   in place. Scoped to >1000px so the <=1000px single-column rule in app.css still wins there. */
/* Round two: minmax(0,1fr) stopped the page overflowing but let the third track collapse to 0px
   at 1010px - the products table simply vanished. Three columns only when the third can actually
   hold a table: 320+320+36 of gap leaves it ~305px once main is >=981px, i.e. a >=1241px viewport
   behind the 245px sidebar. Below that it stacks, exactly as it already does under 1000px. */
@media(min-width:1001px) and (max-width:1240px){.tri{grid-template-columns:1fr}}
@media(min-width:1241px){.tri{grid-template-columns:320px 320px minmax(0,1fr)}}
@media(min-width:1001px){.cols{grid-template-columns:380px minmax(0,1fr)}}

/* ── phone width ──────────────────────────────────────────────────────────────
   At 720px app.css makes the sidebar static, and its thirteen links then stacked into a column
   taller than the screen: the page opened on navigation, never on the work. One scrollable row. */
@media(max-width:720px){
  aside{padding:12px 14px}
  .brand{margin-bottom:10px}
  aside nav{display:flex;flex-wrap:nowrap;overflow-x:auto;gap:4px;padding-bottom:4px}
  aside nav a{flex:0 0 auto;white-space:nowrap;padding:8px 11px}
  aside form .ghost{margin-top:8px}
  .lb-wide{grid-column:auto}
}

/* ── dense tables, read back off the live panel (visual E2E, 2026-09-17) ───────
   `table{width:100%}` makes a table fit its container no matter what is in it, so a column
   holding long free text was squeezed to nothing and the text towered: one /audit row measured
   1,671px tall, the table 56,985px, and the 39,000-row log rendered as a blank white page.
   The two classes that exist to carry long text get a floor; every one of these tables already
   sits in a .scroll-x, so the table scrolls sideways instead of growing downwards.
   Measured after: that row 1,671px -> 163px, the page 57,624px -> 9,628px. */
td.brk{min-width:180px}
td.cell-wide{min-width:320px}

/* A timestamp is digits and punctuation with no strong character, so an RTL paragraph reorders
   its two runs and "2026-09-17 22:55:03" was displayed as "22:55:03 2026-09-17" — the time read
   first. `plaintext` resolves each cell by its own first strong character: Hebrew stays RTL, a
   bare timestamp renders LTR and reads in the right order. */
td{unicode-bidi:plaintext}
.alert .muted,.alert small{unicode-bidi:plaintext}

/* The next-action tile's call to action was a default blue underlined link while the other six
   tiles carry a dark bold one — the same control wearing two appearances. */
.tile>a{color:inherit;text-decoration:none;font-weight:700}
.tile>a:hover{text-decoration:underline}

/* An alert's text sat flush against its own severity bar, with no breathing room. */
.alert:not(.card){padding-inline-start:12px}

/* ── a .cols holding THREE cards ──────────────────────────────────────────────
   .cols is `380px 1fr` — a filter column beside the work. Two screens put a third
   card in it, and a two-track grid wraps that third card onto a row of its own at
   the 380px width of track one. On /integrations that third card is the accounts
   table: 1,156px of content squeezed into a 380px card, scrolling sideways with
   370px of the row left empty beside it, while the middle card sat at 260px with
   its own heading broken over two lines. On /settlements three sibling forms came
   out 380 / 260 / 380.
   With a third child the cards share the row evenly (320px each behind the sidebar
   at 1010px, three ~356px tracks at 1440px), and a table child spans every track so
   it gets the full width. Scoped to >1000px, so the single column app.css gives
   narrow screens still wins there. */
@media(min-width:1001px){
  .cols:has(>:nth-child(3)){grid-template-columns:repeat(auto-fit,minmax(300px,1fr))}
  .cols:has(>:nth-child(3))>.card.table{grid-column:1/-1}
}

/* ── the 380px track was being spent on the wrong card ────────────────────────
   `380px 1fr` reads as "a filter beside the work", but the 380 is charged to
   whatever happens to come first, and behind the sidebar there is not much left to
   charge: at a 1010px window the content strip is 658px, so the second card got
   259px. Measured there: /partners, /links and /budgets gave their filter 380px and
   the data table 275px; /settlements put its 2-row, 353px-wide agreements table in
   the 380px track and squeezed the 23-row, 913px-wide expenses table into 259px;
   /commissions did the same to its two tables. The smaller table got the wider
   track on every one of them.

   Two cards that are both tables have no filter to favour, so they share the row
   evenly - and only while a track can still hold a table (460px), otherwise they
   stack and each gets the full strip. A filter beside a table keeps the designed
   380px, but only from 1180px up, where the work track is still >=430px; below that
   it stacks, the same thing app.css already does below 1000px. (.tri cuts over at
   1241px instead: it is paying for two 320px cards, not one 380px card.)
   Both rules stay above 1000px so the phone layout is untouched. */
@media(min-width:1001px){
  .cols:not(:has(>:not(.card.table))){grid-template-columns:repeat(auto-fit,minmax(460px,1fr))}
}
@media(min-width:1001px) and (max-width:1179px){.cols{grid-template-columns:1fr}}

/* ── the browser's own link colour was still showing through ──────────────────
   app.css gives a link its colour through `nav a` (the sidebar, which the paging strips inherit
   because they are written as <nav>) and, since V2, through `.tile>a`. Four links across the panel
   match neither and were rendering in the user agent's #0000EE underlined default, inside an
   interface that is otherwise dark ink on white.

   They are two different things and get two different answers. The "show the current month"
   switcher is a paging control that happens to sit in a .pager written as a <form>, so the rule
   moves off the element name and onto the class: any .pager styles its own links. The other three
   are cross-references in running text on /links, /settlements and /budgets; they keep the
   underline, which is what marks a link inside a sentence, and take the dark ink so they stand
   clear of the muted grey around them.

   Not `main a`: at two element selectors it ties with `nav a` and wins on order alone, which
   turned every paging control on /conversions, /commissions and /audit from grey to dark. */
.pager a{color:#56606c;text-decoration:none}
main p a{color:#18202a;text-underline-offset:3px}

/* ── MARKER-67 (2026-09-23): contrast and focus in the light scheme (P9.3) ───────
   m67/contrast.py measures every text/background pair these stylesheets produce against WCAG AA.
   Six light pairs were under the 4.5:1 floor for body text: the muted grey #7b8590 that carries
   every secondary line, table header, legend and hint (3.5:1 on the page, 3.75:1 on a card); the
   brand line under the logo (3.1:1); the small label above each h1 (2.9:1); the header paragraph
   (3.95:1); the login paragraph (4.2:1); and the provenance warning glyph #b26a00 (4.2:1), which is
   text too. One grey, #5f6b77, now serves every one of the grey roles: 4.8:1 on the darkest light
   surface it sits on (#eef1f4), 5.45:1 on white. Nothing else about them changes.
   Two edges were under the 3:1 floor for controls and state (WCAG 1.4.11): the form-field border
   #d9dfe7 (1.3:1 — the only edge of a white field on a white card) and the warning alert's severity
   bar #e1a12c (2.3:1 — the only mark of its severity). #848e9a is 3.3:1 on white, #b57412 3.8:1.
   Focus: only the command-center tiles had a :focus-visible style; every other control fell back to
   the browser's own ring, which differs per browser and all but disappears on a near-black button.
   One rule gives every focusable element the same 2px ring, offset so it is drawn on the surface
   around the control rather than on the control's own fill. app-dark.css recolours it for dark. */
.brand small,header span,header p,.auth p,th,.muted,.ack legend{color:#5f6b77}
.prov-flag{color:#8f5600}
.form input,.form select,.form textarea,.linkbank td select,.linkbank td input[name=integration_id]{border-color:#848e9a}
.alert.warning{border-right-color:#b57412}
:focus-visible{outline:2px solid #151a21;outline-offset:2px}
/* At phone width the sidebar links scroll sideways inside `aside nav`, whose overflow clips anything
   drawn outside it — the top of a focus ring on the first row included. Room for the ring. */
@media(max-width:720px){aside nav{padding:4px}}

/* MARKER-69 (2026-09-23): 390px overflow found by the E6 browser sweep. The status pager wrapped only inside .linkbank;
   a .tri item kept min-width:auto, so a wide table widened the one mobile track; an unbreakable <code> (the OAuth
   callback URL) set the min-content of the integrations form track - scoped to phone width in forms so no desktop table
   reflows. Each rule has a page that overflows without it. */
.pager{flex-wrap:wrap}
.tri>*{min-width:0}
@media(max-width:720px){.form code{overflow-wrap:anywhere}}
