/* The visual system, decided in the build plan before any screen was written.
   Colours are the workbooks' own (xlsx_style.py) except muted text and the
   amber, both darkened to clear WCAG AA on screen. */
:root {
  --ground: #F7F8FA; --surface: #FFFFFF; --ink: #1F2933; --body: #3E4C59;
  --muted: #616E7C; --rule: #CBD2D9; --rule-soft: #E4E8ED;
  --accent: #1B7A56; --accent-soft: #DFF5E1; --computed: #FDF3D8;
  --warn: #8A5A0E; --warn-soft: #FDE8C8; --bad: #9B2C2C; --bad-soft: #F5C0C0;
  --code-bg: #EEF1F4;
  --sans: "IBM Plex Sans", "Helvetica Neue", Arial, sans-serif;
  --mono: "IBM Plex Mono", Menlo, Consolas, monospace;
  color-scheme: light;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --ground: #151A20; --surface: #1F2933; --ink: #EEF2F5; --body: #C9D1D9;
    --muted: #95A2AF; --rule: #3E4C59; --rule-soft: #2C3640; --accent: #5DC79A;
    --accent-soft: #1D3A2E; --computed: #3A3320; --warn: #E0A84A; --warn-soft: #3A2E15;
    --bad: #E28B8B; --bad-soft: #452222; --code-bg: #29333D; color-scheme: dark;
  }
}
:root[data-theme="dark"] {
  --ground: #151A20; --surface: #1F2933; --ink: #EEF2F5; --body: #C9D1D9;
  --muted: #95A2AF; --rule: #3E4C59; --rule-soft: #2C3640; --accent: #5DC79A;
  --accent-soft: #1D3A2E; --computed: #3A3320; --warn: #E0A84A; --warn-soft: #3A2E15;
  --bad: #E28B8B; --bad-soft: #452222; --code-bg: #29333D; color-scheme: dark;
}

* { box-sizing: border-box; }
body { margin: 0; background: var(--ground); color: var(--body); font-family: var(--sans); font-size: 15px; line-height: 1.55; -webkit-font-smoothing: antialiased; }
a { color: var(--accent); text-underline-offset: 3px; text-decoration-thickness: 1px; }
::selection { background: var(--accent-soft); color: var(--ink); }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.shell { display: grid; grid-template-columns: 200px minmax(0, 1fr); min-height: 100vh; }
.rail { display: flex; flex-direction: column; background: var(--surface); border-right: 1px solid var(--rule-soft); padding: 20px 0; }
.rail .brand { padding: 0 20px 14px; font-weight: 600; color: var(--ink); }
.rail a { display: block; padding: 7px 20px; color: var(--body); text-decoration: none; }
.rail a.current { color: var(--ink); font-weight: 500; background: var(--ground); }
/* Who is signed in, pinned to the foot of the rail: the name, the role as a
   chip, and the way out. The chip says what the person may change. */
.rail .account { margin-top: auto; padding: 14px 20px 0; border-top: 1px solid var(--rule-soft); font-size: 13px; }
.rail .account .who { color: var(--ink); font-weight: 500; overflow-wrap: anywhere; }
.rail .account .row { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 6px; }
.rail .account a { padding: 0; color: var(--accent); }
.content { padding: 32px 40px 64px; max-width: 1120px; }
@media (max-width: 860px) { .shell { grid-template-columns: 1fr; } .rail { border-right: 0; border-bottom: 1px solid var(--rule-soft); } .rail .account { margin-top: 14px; } .content { padding: 20px; } }

/* The signed-out pages: no rail, one column, the same type as everything else. */
.wall { max-width: 480px; margin: 0 auto; padding: 96px 24px 64px; }
.wall p { margin-bottom: 20px; }
@media (max-width: 860px) { .wall { padding-top: 48px; } }

h1 { font-size: 24px; font-weight: 600; color: var(--ink); letter-spacing: -.01em; margin: 0 0 4px; text-wrap: balance; }
h2 { font-size: 17px; font-weight: 600; color: var(--ink); margin: 32px 0 10px; }
p { max-width: 68ch; margin: 0 0 12px; }
.sub { color: var(--muted); }
.label { font-size: 11.5px; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); font-weight: 500; }
code, .mono { font-family: var(--mono); font-size: 13.5px; }
.num { font-family: var(--mono); font-variant-numeric: tabular-nums; text-align: right; }

table { border-collapse: collapse; width: 100%; font-size: 14px; }
th { text-align: left; font-size: 11.5px; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); font-weight: 500; padding: 7px 12px; border-bottom: 1px solid var(--rule); }
th.num { text-align: right; }
td { padding: 8px 12px; border-bottom: 1px solid var(--rule-soft); vertical-align: middle; white-space: nowrap; }
td:first-child { font-weight: 500; color: var(--ink); }
tr:nth-child(even) td { background: var(--ground); }
tr.sub td:first-child { color: var(--muted); font-weight: 400; padding-left: 28px; }
tr.sub td { color: var(--muted); }
tr.total td { border-top: 2px solid var(--ink); border-bottom: 0; font-weight: 600; color: var(--ink); background: none; }
td.neg { color: var(--bad); }
.tablewrap { overflow-x: auto; }

.chip { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 500; padding: 2px 9px 2px 7px; border-radius: 999px; white-space: nowrap; }
.chip::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.chip.ok { color: var(--accent); background: var(--accent-soft); }
.chip.todo { color: var(--warn); background: var(--warn-soft); }
.chip.bad { color: var(--bad); background: var(--bad-soft); }
.chip.wait { color: var(--muted); background: var(--code-bg); }

.in { font-family: var(--sans); font-size: 14px; color: var(--ink); background: var(--surface); border: 1px solid var(--rule); border-radius: 3px; padding: 7px 10px; }
.in.num { font-family: var(--mono); text-align: right; font-variant-numeric: tabular-nums; }
.in.fill { background: var(--accent-soft); border-color: var(--accent-soft); }
.in.auto { background: var(--computed); border-color: var(--computed); }
.in.err { border-color: var(--bad); background: var(--bad-soft); }
.err-msg { font-size: 12.5px; color: var(--bad); margin-top: 4px; }
select.in { appearance: none; padding-right: 28px; }

.btn { display: inline-block; font-family: var(--sans); font-size: 14px; font-weight: 500; line-height: 1.4; padding: 8px 16px; border-radius: 3px; border: 1px solid var(--rule); background: var(--surface); color: var(--ink); cursor: pointer; text-decoration: none; }
.btn.primary { background: var(--ink); color: var(--ground); border-color: var(--ink); }
.btn.danger { color: var(--bad); border-color: var(--bad); }
.btn.quiet { border-color: transparent; color: var(--accent); }
.btn:disabled { opacity: .5; cursor: default; }

.banner { background: var(--bad-soft); color: var(--ink); padding: 10px 14px; font-size: 14px; border-radius: 3px; margin: 0 0 12px; }
.banner b { color: var(--bad); }
.notice { background: var(--warn-soft); padding: 10px 14px; font-size: 14px; border-radius: 3px; margin: 0 0 12px; }
.empty { border: 1px dashed var(--rule); padding: 18px; text-align: center; color: var(--muted); font-size: 14px; }
.empty b { color: var(--ink); display: block; font-weight: 500; margin-bottom: 4px; }
.log { background: var(--ink); color: #DCE3EA; font-family: var(--mono); font-size: 12.5px; line-height: 1.55; padding: 12px 14px; border-radius: 4px; overflow-x: auto; margin: 0; }

/* month + operator */
/* The head of a screen: title and caption on the left, the month picker on
   the right. A section is one numbered step of the operator's month. */
.head { display: flex; justify-content: space-between; align-items: flex-start; gap: 24px; flex-wrap: wrap; }
.toolbar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.toolbar label { font-size: 13px; color: var(--muted); }
.summary { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 16px; margin: 16px 0 12px; max-width: none; }
.summary .figure { font-size: 24px; font-weight: 500; color: var(--ink); text-align: left; }
.actions { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; margin-top: 24px; }
.files { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 16px; }
.section { margin-top: 40px; }
.section h2 { margin-top: 0; }
h3 { font-size: 15px; font-weight: 600; color: var(--ink); margin: 24px 0 6px; }
/* The invoice's figures: labels and mono values in a row, not tiles. */
.figures { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, max-content)); gap: 8px 40px; margin: 0 0 16px; }
.figures div { display: flex; flex-direction: column; gap: 2px; }
.figures dt, .figures dd { margin: 0; }
.figures .num { font-size: 17px; color: var(--ink); text-align: left; }
/* The figures forms: one group per studio, one row per brand. */
.group { margin: 12px 0 20px; }
.group .key { font-family: var(--mono); font-size: 13px; color: var(--ink); }
.group .bands { font-size: 13px; color: var(--muted); margin: 0 0 8px; }
.grid { display: grid; grid-template-columns: minmax(180px, max-content) 200px max-content; gap: 8px 16px; align-items: center; }
.grid .brand { font-family: var(--mono); font-size: 13px; }
.grid .tick { display: flex; align-items: center; gap: 6px; font-size: 13px; color: var(--muted); }
.grid .err-msg { grid-column: 2 / -1; margin-top: -4px; }
@media (max-width: 860px) { .grid { grid-template-columns: 1fr; gap: 4px; } .grid .brand { margin-top: 8px; } .grid .err-msg { grid-column: 1; } }
td.wrap { white-space: normal; min-width: 320px; font-size: 13px; color: var(--body); }
ul.plain { margin: 8px 0 0; padding-left: 18px; font-size: 14px; }
.notice b { color: var(--warn); }
input[type="file"].in { padding: 5px 10px; }

/* rates + provider */
/* An editable table: the cells are inputs, so the row padding comes from
   them and the reason a row was refused sits under it in its own row. */
table.edit td { padding: 4px 6px; }
table.edit td:first-child { padding-left: 12px; }
table.edit .in { width: 100%; min-width: 64px; }
table.edit select.in { min-width: 140px; }
tr.refused td { background: var(--bad-soft); }
tr.refused-why td { padding: 0 12px 8px; border-bottom: 1px solid var(--rule); white-space: normal; background: none; }
tr.refused-why .err-msg { margin-top: 0; }
/* A checkbox in a toolbar sits with its words, not under them. */
.toolbar .check { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; color: var(--muted); }
.upload { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-top: 12px; }
.upload label { font-size: 13px; color: var(--muted); }
.actions label { font-size: 13px; color: var(--muted); }
.actions .sub, .upload .sub { font-size: 13px; }

/* jobs */
/* The jobs screen and a job's page. The log is the plan's specimen: the
   CLI's own lines on ink, warnings and results keeping their meaning through
   colour, nothing paraphrased. Three tints, all clearing 4.5:1 on the ink. */
.log .ok { color: #9BE4BE; }
.log .warn { color: #F2C879; }
.log .bad { color: #F4A9A9; }
.jobs-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 24px; flex-wrap: wrap; margin-bottom: 24px; }
.jobs-toolbar { display: flex; align-items: center; gap: 8px; }
.jobs-toolbar label { font-size: 13px; color: var(--muted); }
.jobs-status { padding-top: 6px; }
.jobs-start { display: grid; gap: 16px; padding: 16px 0; border-top: 1px solid var(--rule-soft); border-bottom: 1px solid var(--rule-soft); }
.jobs-operator { display: grid; grid-template-columns: auto auto minmax(0, 1fr); align-items: center; gap: 12px; }
.jobs-operator label { font-size: 13px; color: var(--muted); }
.jobs-operator .sub { font-size: 13px; }
.jobs-actions { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 16px; }
.jobs-action .btn { width: 100%; }
.jobs-action .sub { font-size: 13px; margin: 8px 0 0; }
.jobs-files { margin: 0; padding-left: 20px; }
.jobs-files li { margin: 4px 0; font-family: var(--mono); font-size: 13.5px; }
.jobs-back { margin-top: 24px; }
.promos-notes { max-width: 68ch; padding-left: 20px; }
.promos-notes li { margin: 4px 0; }
@media (max-width: 860px) { .jobs-operator { grid-template-columns: 1fr; } }

/* htmx: what a request looks like while it is in flight, and the one
   transition. A cell being saved dims and cannot be typed into until the
   server answers; a button that starts work shows its spinner and swaps its
   words for what is happening. A swapped-in row fades in over 150 ms and
   not at all under prefers-reduced-motion. */
.in.htmx-request, tbody.htmx-request .in { opacity: .6; }
.btn .spin { display: none; width: 12px; height: 12px; margin-right: 8px; vertical-align: -1px; border-radius: 50%; background: conic-gradient(currentColor 0 270deg, transparent 270deg 360deg); -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 2px), #000 calc(100% - 2px)); mask: radial-gradient(farthest-side, transparent calc(100% - 2px), #000 calc(100% - 2px)); animation: turn 700ms linear infinite; }
.btn.htmx-request .spin { display: inline-block; }
.btn .busy { display: none; }
.btn.htmx-request .busy { display: inline; }
.btn.htmx-request .idle { display: none; }
@keyframes turn { to { transform: rotate(360deg); } }
@keyframes settle { from { opacity: 0; } to { opacity: 1; } }
tr.htmx-settling, tbody.htmx-settling > tr, .swap.htmx-settling { animation: settle 150ms ease-out; }
@media (prefers-reduced-motion: reduce) {
  tr.htmx-settling, tbody.htmx-settling > tr, .swap.htmx-settling, .btn .spin { animation: none; }
}
/* An editable table keeps each studio in its own tbody, so a row and the
   reason it was refused are one thing to swap. Banding is then by studio. */
table.edit tbody > tr:nth-child(even) td { background: none; }
table.edit tbody:nth-of-type(even) > tr:first-child td { background: var(--ground); }
table.edit tbody > tr.refused td, table.edit tbody:nth-of-type(even) > tr.refused:first-child td { background: var(--bad-soft); }

/* pricing: studios, deals, terms */
.rail-section { font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); margin: 18px 0 4px; padding: 0 12px; }
.rail-section:first-of-type { margin-top: 6px; }
.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 16px; margin: 16px 0; }
.card { background: var(--surface); border: 1px solid var(--rule-soft); border-radius: 12px; padding: 16px 18px; }
.card h2, .card h3 { margin-top: 0; }
.card .deal { font-size: 17px; color: var(--ink); font-weight: 500; }
.card .deal .mono { font-weight: 400; }
.card .meta { color: var(--muted); font-size: 13px; margin: 4px 0 0; }
.badge { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 500; padding: 2px 10px; border-radius: 999px; background: var(--code-bg); color: var(--body); white-space: nowrap; }
.badge.ok { background: var(--accent-soft); color: var(--accent); }
.badge.warn { background: var(--warn-soft); color: var(--warn); }
.badge.bad { background: var(--bad-soft); color: var(--bad); }
.pills { display: flex; flex-wrap: wrap; gap: 6px; }
.pills label { display: inline-flex; align-items: center; gap: 5px; font-size: 12.5px; padding: 3px 10px; border-radius: 999px; border: 1px solid var(--rule); cursor: pointer; }
.pills label:has(input:checked) { background: var(--ink); color: var(--ground); border-color: var(--ink); }
.pills input { display: none; }
.termrow { display: grid; grid-template-columns: 180px 1fr auto; gap: 12px; align-items: center; padding: 10px 0; border-bottom: 1px solid var(--rule-soft); }
.termrow:last-child { border-bottom: 0; }
.termrow .note { color: var(--muted); font-size: 13px; }
.why { color: var(--muted); font-size: 13px; white-space: normal; }
td.why { white-space: normal; max-width: 420px; }
td.wrap { white-space: normal; }
details.editor { margin-top: 10px; }
details.editor summary { cursor: pointer; color: var(--accent); font-size: 14px; font-weight: 500; list-style: none; }
details.editor summary::before { content: "+ "; }
details.editor[open] summary::before { content: "– "; }
details.editor form { margin-top: 10px; padding: 12px 14px; background: var(--ground); border-radius: 8px; }
.fields { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 8px 12px; margin-bottom: 10px; }
.fields label { display: flex; flex-direction: column; gap: 3px; font-size: 12px; color: var(--muted); }
.fields label .in { width: 100%; box-sizing: border-box; }
.fields label.wide { grid-column: 1 / -1; }
.price { display: flex; gap: 12px; align-items: flex-end; flex-wrap: wrap; }
.price .result { font-size: 22px; font-weight: 500; color: var(--ink); font-family: var(--mono); }
.kpis { display: flex; flex-wrap: wrap; gap: 4px 28px; margin: 12px 0 16px; }
.kpis div { display: flex; flex-direction: column; }
.kpis .figure { font-size: 24px; font-weight: 500; color: var(--ink); }
.kpis .label { font-size: 12px; color: var(--muted); text-transform: uppercase; letter-spacing: .05em; }
tr.dev td { background: var(--computed) !important; }

/* Provider payables: a table whose rows open. Each provider is a <details>
   whose <summary> lays out on the same grid as the header row. */
.ledger { border: 1px solid var(--rule); background: var(--surface); }
.ledger-row { display: grid; grid-template-columns: minmax(200px, 2.4fr) 0.6fr 1.2fr 1.2fr 1.1fr 1.1fr; gap: 12px; align-items: center; padding: 10px 14px; border-bottom: 1px solid var(--rule); font-size: 14px; }
.ledger-head { font-family: var(--mono); font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.ledger-item > summary { cursor: pointer; list-style: none; }
.ledger-item > summary::-webkit-details-marker { display: none; }
.ledger-item > summary > span:first-child::before { content: "+"; display: inline-block; width: 16px; color: var(--accent); font-weight: 600; }
.ledger-item[open] > summary > span:first-child::before { content: "\2013"; }
.ledger-item > summary:hover, .ledger-item > summary:focus-visible { background: var(--ground); }
.ledger-item[open] > summary { background: var(--accent-soft); }
.ledger-detail { padding: 4px 14px 14px 30px; border-bottom: 1px solid var(--rule); }
.ledger-total { border-bottom: 0; }
@media (max-width: 760px) {
  .ledger-row { grid-template-columns: 1fr 1fr; }
  .ledger-head { display: none; }
}
