/*
 * public/assets/css/panel.css — the owner panel's styling, all of it (§11).
 *
 * A FILE, not the inline <style> §11 originally asked for. The guarantee that
 * block was protecting is unchanged: the panel shares no stylesheet with the
 * tenant system. Nothing else links this, it imports nothing, the panel links
 * nothing else, and the suite pins all three. With no inline styles left, the
 * panel also sends a CSP with no 'unsafe-inline' in style-src.
 *
 * ── BLOCKS, NOT A DOCUMENT ──────────────────────────────────────────────
 *
 * NOTHING IS SPACED APART. No gaps, no margins between elements, no rules and
 * no borders: every region is a solid field of colour meeting the next one
 * flush. Padding exists only INSIDE a block, to keep its own text off its own
 * edge.
 *
 * COLOUR IS THEREFORE THE SEPARATOR, and that is why the borders went. The
 * standing rule holds — one property per distinction — and colour is now the
 * property doing it. A hairline between two blocks that are already different
 * colours would be the second factor the rule exists to prevent.
 *
 * ── COLOUR MEANS SOMETHING ──────────────────────────────────────────────
 *
 * Four hues, each with one job, so the palette is read rather than admired:
 *
 *   GREEN   a constructive action, or a state that is fine
 *   RED     a destructive action, or a state that wants attention now
 *   YELLOW  something waiting on a person — pending, unverified, drifted
 *   BLUE    neutral structure: navigation, identity, things that are facts
 *
 * A hue's own SHADES group what belongs together. A field, its label and its
 * hint are three steps of one colour, which says "these are one thing" without
 * a box drawn round them — the job a border used to do.
 *
 * Greys stay fully desaturated (r = g = b). Colour is for meaning; when
 * nothing is being meant, the answer is paper and ink.
 *
 * ── AND STILL ───────────────────────────────────────────────────────────
 *
 * ONE TYPE SIZE. --size is everything; --size-s exists for one job, long text
 * in a narrow cell, and <small> is its only user.
 *
 * AS LITTLE TEXT AS POSSIBLE. One person reads this panel and already knows
 * what it does. Prose earns its place only by explaining a refusal or naming a
 * consequence — never by labelling the obvious.
 */

:root {
    /*
     * DARK, AND ONLY DARK. One person uses this panel and works at night, so
     * there is no light palette to keep in step and no media query to reason
     * about — the file halves and every colour below can be chosen against one
     * known ground instead of two.
     */
    color-scheme: dark;

    --size:   13px;
    --size-s: 11px;

    /* Desaturated, as ever: ink and secondary text carry no hue. */
    --paper:  #141414;
    --ink:    #e8e8e8;
    --muted:  #8c8c8c;

    /*
     * EACH HUE IS A FOUR-STEP RAMP, and every step means the same thing in
     * every hue:
     *
     *   -1  structure: a heading band, or a field's label
     *   -2  the body under it — the block itself
     *   -3  something you can act on: a button, an input
     *   -4  that same thing under the pointer
     *
     * FOUR AND NOT THREE, because with three the body and an unhovered button
     * were the same colour: a control with nothing separating it from the
     * surface it sits on. Every hue gets all four even where only some are
     * used yet, so a ramp is never extended in a hurry to fit one screen.
     *
     * THE STEPS ARE GENERATED, not picked: each is nine units of luminance
     * above the last, scaled on the whole triple so the hue holds. Tinting
     * toward white would have washed the colour out as it rose, and the ramps
     * would not have been parallel.
     *
     * Small on purpose. A ramp exists to say "these blocks belong together";
     * far enough apart and it says the opposite. On a dark ground every step
     * is dark, so text stays --ink throughout and no block needs its own
     * foreground rule.
     */

    /* GREEN — constructive, or fine. */
    --go:   #5fce8f;
    --go-1: #17251d;
    --go-2: #1d2f25;
    --go-3: #243a2d;
    --go-4: #2a4436;

    /* RED — destructive, or wrong. */
    --no:   #f08070;
    --no-1: #2a1a17;
    --no-2: #36221e;
    --no-3: #432925;
    --no-4: #4f312b;

    /* YELLOW — waiting on a person. */
    --wait:   #e8c05a;
    --wait-1: #262014;
    --wait-2: #31291a;
    --wait-3: #3b321f;
    --wait-4: #463b25;

    /*
     * GREY — THE DEFAULT, and the absence of a claim.
     *
     * Anything that is merely structure takes this: the bar, a heading with no
     * opinion, a table, a control that does nothing in particular. Blue used
     * to sit here and it was wrong — a hue on every screen is a hue that has
     * stopped meaning anything, and the panel then has four colours of which
     * one is just "background".
     *
     * Fully desaturated, and the same four steps as every hue.
     */
    --flat-1: #1e1e1e;
    --flat-2: #272727;
    --flat-3: #303030;
    --flat-4: #393939;

    /*
     * BLUE — A WHOLE BLOCK, SET APART.
     *
     * Not a default and not a per-element accent: when a region needs to read
     * as its own thing rather than more of the page, the whole region takes
     * blue and its four shades do the work inside it — heading, body, control,
     * hover. Used on one block today, the create form, which is the only place
     * on the accounts screen that is an input area rather than a listing.
     *
     * An ACTION inside such a block keeps its own colour. The hue says which
     * region you are in; green and red say what a press will do, and that
     * question is not answered by where the button happens to sit.
     */
    --nav:   #8fb0f0;
    --nav-1: #1a2133;
    --nav-2: #212a41;
    --nav-3: #28334f;
    --nav-4: #2f3c5d;

    /* The row ramp. */
    --row-1: #1a1a1a;
    --row-2: #1e1e1e;

    /* The way out of a question is a control with no claim: --flat-3, like
       any other neutral control. It had its own pair of greys until the flat
       ramp existed to hold them. */
}

* { box-sizing: border-box; }

body {
    margin: 0;
    background: var(--paper);
    color: var(--ink);
    font: var(--size)/1.45 ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
}

/* ---- the bar ------------------------------------------------------- */

/* Solid blue: identity and navigation, the one region that is the same on
   every screen. It is a block, so it runs edge to edge and sits flush on
   whatever follows. */
header {
    display: flex;
    align-items: stretch;
    background: var(--flat-1);
}

/* The title IS the overview link — there is no separate "Overview" item,
   because a nav entry pointing where the title already points is a word that
   earns nothing. */
header h1 {
    margin: 0;
    font-size: inherit;
    font-weight: inherit;
    text-transform: uppercase;
}

header a {
    display: flex;
    align-items: center;
    padding: 0.7rem 1.1rem;
    color: inherit;
    text-decoration: none;
}

/* Hover is a block filling, not an underline: the same language as
   everything else here. */
header a:hover { background: var(--flat-3); }

header nav { display: flex; }
header .who {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 1rem;
    padding-left: 1.1rem;
    color: var(--muted);
}
header .who form { display: flex; }
header .who button {
    border: 0;
    background: transparent;
    color: var(--muted);
    font: inherit;
    padding: 0.7rem 1.1rem;
    cursor: pointer;
}
header .who button:hover { background: var(--no-3); }

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

/* No padding on main: its children are blocks and must reach the edges. */
main { padding: 0; }

/* A heading is a band of its own — uppercase and nothing else, on a colour
   that says which kind of section follows. */
/*
 * A HEADING TAKES THE HUE OF WHAT IT INTRODUCES, one step deeper. Blue is the
 * default, for a section whose content is neutral — a table of facts.
 *
 * `:has(+ .good)` asks what the NEXT ELEMENT is, which is the rule stated
 * exactly: the heading is not deciding a colour, it is inheriting the one its
 * content already earned. Without it the operator reads a blue band, then a
 * green one, and has to join them up.
 */
/*
 * TALL, WITH THE WORD ON THE FLOOR. Three times the height it needs, text
 * aligned to the bottom — a keycap, not a caption. The empty space above is
 * the block doing the separating that the removed margins used to do, and it
 * is the same single factor: colour, in a shape.
 */
h2 {
    margin: 0;
    padding: 0.5rem 1.1rem;
    min-height: 3.9rem;
    display: flex;
    align-items: flex-end;
    font-size: inherit;
    font-weight: inherit;
    text-transform: uppercase;
    background: var(--flat-1);
}
h2:has(+ .good) { background: var(--go-1); }
/* A heading that introduces a question takes the question's colour too —
   `.confirm` is a <div>, so the `+ .wait` rule above cannot see it. */
/* A QUESTION ABOUT SOMETHING DESTRUCTIVE IS RED THROUGHOUT. It was yellow —
   waiting on a person — with a red button inside it, which is two states in
   one block. The band asks and the button acts; both are about the same
   dangerous thing, so both are the same colour. */
h2.asking, h2:has(+ .confirm) { background: var(--no-1); }

/*
 * BLUE BLOCKS. A heading belongs to the block it introduces, so each region
 * starts at the top of its words rather than at the top of its content.
 *
 * `.count` is a STATUS — a number that is neither good nor bad and is still a
 * banner rather than body text. Green would congratulate it and red would
 * alarm; blue sets it apart without claiming anything about it.
 */
h2:has(+ form.create) { background: var(--nav-1); }

/*
 * THE TALLY: THREE BLOCKS, NOT THREE COLOURED NUMBERS.
 *
 * Each column is its own field of colour meeting the next one flush, which is
 * the same language as the rest of the panel. Coloured figures on a shared
 * ground read as three labels; filled columns read as three blocks, which is
 * what they are.
 *
 * This is NOT the `td.good` rule (§6.117) being reversed. That one is about a
 * status sitting in a row that ends in buttons, where a fill reads as one more
 * thing to press. There is nothing to press here — the whole row is the
 * content.
 *
 * The figures are large because they are the content rather than a label for
 * it: an `em` multiple of the one type size, not a third size.
 */
table.counts    { width: 100%; }
table.counts th { font-weight: inherit; color: var(--ink); }

/*
 * THE FIGURES ARE THE ONE PLACE WITH A SECOND TYPEFACE, and the exception is
 * narrow on purpose: everything else in this panel is the monospace the rest
 * of it is set in, because everything else is a label, a field or a fact in a
 * row. These are the content.
 *
 * A SYSTEM STACK, no webfont. `-apple-system` resolves to SF Pro, which ships
 * real Ultralight and Thin cuts — so `font-weight: 200` is a drawn weight
 * rather than a synthesised one, and large type stays quiet instead of
 * shouting. On a system without them the fallback is the platform sans at its
 * lightest available weight, which degrades to "slightly less heavy" rather
 * than to anything broken.
 *
 * Size and weight pull in opposite directions here deliberately: big enough to
 * be the thing you look at first, thin enough not to be the thing you cannot
 * look away from. Low opacity was the alternative and would have cost contrast
 * that §11's dark ground has little of to give.
 */
table.counts td {
    font-family: ui-sans-serif, -apple-system, "Segoe UI", "Helvetica Neue", Arial, sans-serif;
    font-size: 6em;
    font-weight: 200;
    line-height: 1;
    letter-spacing: -0.02em;
    padding: 0.05em 1.1rem 0.12em;
}

/* The link inherits the figure entirely — it is the number that is pressable,
   not a word beside it. */
table.counts td a { color: inherit; text-decoration: none; }
table.counts td a:hover { text-decoration: underline; }

/* Heading one step deeper than the block it introduces, as everywhere else.
   The total is grey: a sum of three states is not itself a state. */
th.is-total   { background: var(--flat-1); }
td.is-total   { background: var(--flat-2); }
th.is-active  { background: var(--go-1); }
td.is-active  { background: var(--go-2); }
th.is-waiting { background: var(--nav-1); }
td.is-waiting { background: var(--nav-2); }
th.is-blocked { background: var(--no-1); }
td.is-blocked { background: var(--no-2); }

/* The tally's rows are blocks in their own right and must not take the zebra
   or gradient shading the data tables use. */
table.counts tbody tr { background: none; }
h2:has(+ .bad)  { background: var(--no-1); }
h2:has(+ .wait) { background: var(--wait-1); }

p { margin: 0; padding: 0.4rem 1.1rem; }
a { color: var(--nav); }
code { font: inherit; }
small { font-size: var(--size-s); color: var(--muted); }

/* The application is written with newlines and read as written: it is the one
   cell whose line breaks carry meaning, because a person put them there. */
td.application { white-space: pre-line; }

/* ---- tables -------------------------------------------------------- */

table { border-collapse: collapse; width: 100%; }
th, td { padding: 0.35rem 1.1rem; text-align: left; vertical-align: top; white-space: nowrap;}

/* Muted alone, on paper. The head is not data and that is all it has to say. */
thead th { font-weight: inherit; color: var(--muted); }

/*
 * ROWS: A GRADIENT WHILE THERE ARE FEW, ZEBRA ONCE THERE ARE MANY.
 *
 * A short table reads better as a descending wash — it shows at a glance how
 * many rows there are, which a repeating pair cannot. Past about eight that
 * stops working: the steps get too close to tell apart, and what the eye
 * actually needs is only "this line is not the one above it".
 *
 * `tbody:has(tr:nth-child(9))` asks the table how long it is, which is the
 * rule stated exactly. It costs one selector and no JavaScript.
 */
tbody tr:nth-child(1) { background: #1c1c1c; }
tbody tr:nth-child(2) { background: #1f1f1f; }
tbody tr:nth-child(3) { background: #222222; }
tbody tr:nth-child(4) { background: #252525; }
tbody tr:nth-child(5) { background: #282828; }
tbody tr:nth-child(6) { background: #2b2b2b; }
tbody tr:nth-child(7) { background: #2e2e2e; }
tbody tr:nth-child(8) { background: #313131; }

tbody:has(tr:nth-child(9)) tr:nth-child(odd)  { background: var(--row-1); }
tbody:has(tr:nth-child(9)) tr:nth-child(even) { background: var(--row-2); }

/* ---- state --------------------------------------------------------- */

/*
 * A BAND IS FILLED; A CELL IS COLOURED TEXT. Same single factor, two shapes,
 * and the shape is chosen by what the thing sits next to.
 *
 * A <p> is a full-width banner with nothing to be confused with, so it takes
 * the fill. A <td> sits in a row that ends in BUTTONS — and a filled cell
 * beside them reads as another one, which is a thing to press rather than a
 * fact to read.
 *
 * Coloured text was the first version everywhere, and was dropped on the
 * argument that it would not survive the row shading. That was true of the
 * light palette it was written for; on the dark ground the accents clear 6:1
 * against both zebra rows, which is not close.
 */
p.good, p.bad, p.wait { color: var(--ink); }
p.good { background: var(--go-2); }
p.bad  { background: var(--no-2); }
p.wait { background: var(--wait-2); }

/* The bright end of each ramp, which until now had no job. */
td.good { color: var(--go); }
td.bad  { color: var(--no); }
td.wait { color: var(--wait); }

/* ---- messages ------------------------------------------------------ */

/* Full-width bands. Which colour IS the message; the words only say what
   happened. */
.notice, .error { margin: 0; padding: 0.6rem 1.1rem; }
.notice  { background: var(--go-2); }   /* it worked */
.error   { background: var(--no-2); }   /* it did not */

/*
 * NO PADDING ON THE BAND ITSELF. Its children carry their own, so the action
 * row at the bottom reaches all four edges — a full-width press with a margin
 * round it is a button sitting in a box, which is the shape everything else
 * here stopped being.
 */
.confirm { margin: 0; padding: 0; background: var(--no-2); }
.confirm p { padding: 0.5rem 1.1rem; }
/* Already inside a red band; a second red would be the same state twice. */
.confirm p.bad { background: transparent; }
.confirm label { display: block; padding: 0.5rem 1.1rem 0.2rem; background: var(--no-1); }

/* ---- controls ------------------------------------------------------ */

/*
 * BUTTONS ARE THEIR MEANING. No border, no radius: the fill is the whole
 * signal, and green or red says what a press will do before the label is read.
 * Blue is a press that changes nothing.
 *
 * COLOURED BY WHAT THEY SUBMIT, not by where they sit. Each action form
 * carries a hidden `action` input, so `form:has(input[value="delete"])` reads
 * the intent straight off the markup — which means a new destructive action
 * is red by being NAMED, never by someone remembering to come here.
 */
form { display: inline; }

button {
    font: inherit;
    border: 0;
    padding: 0.35rem 0.9rem;
    cursor: pointer;
    background: var(--flat-3);
    color: var(--ink);
	white-space: nowrap;
}
button:hover { background: var(--flat-4); }

/* The decision is a hidden input, never an attribute on the button — the
   markup deliberately does not depend on WHICH button was pressed — so these
   read the form, not the control. `button[value="approve"]` matched nothing. */
form:has(input[value="house"])   button,
form:has(input[value="unblock"]) button,
form:has(input[value="approve"]) button         { background: var(--go-3); }
form:has(input[value="house"])   button:hover,
form:has(input[value="unblock"]) button:hover,
form:has(input[value="approve"]) button:hover   { background: var(--go-4); }

form:has(input[value="block"])   button,
form:has(input[value="delete"])  button,
form:has(input[value="reject"])  button,
.who button                                     { background: var(--no-3); }
form:has(input[value="block"])   button:hover,
form:has(input[value="delete"])  button:hover,
form:has(input[value="reject"])  button:hover   { background: var(--no-4); }

/*
 * THE ROW OF PER-ACCOUNT ACTIONS: three blocks touching, separated by colour
 * and nothing else.
 *
 * `display: flex` on the cell, because the forms are inline elements and the
 * newlines between them in the template render as spaces — a gap that is
 * invisible in the markup and very visible on screen. Flex discards it, which
 * is the whole reason it is here; the cell keeps its padding at zero so the
 * blocks reach the cell's own edges.
 */
/*
 * FLEX ON THE CELL, not on each form. With `display: flex` on the FORMS, each
 * one became a block-level flex container and they stacked into a column —
 * the opposite of the point. The cell is the container; the forms are its
 * items, sitting in a row with the template's newlines discarded.
 */
td.actions { display: flex; padding: 0; }
td.actions button { padding: 0.35rem 0.8rem; }

/*
 * Export is a GET — it changes nothing — so it is a form with method="get"
 * rather than a POST dressed up as one. That makes it a real button.
 *
 * BLUE, because the column is a block: every cell in it does the same distinct
 * thing, which is what a whole-block colour is for. It is neither
 * constructive nor destructive, so green and red would both be lies, and flat
 * grey said "no opinion" about the one action on this screen that is neither.
 */
td.export { padding: 0; }
td.export button { width: 100%; text-align: left; background: var(--nav-3); }
td.export button:hover { background: var(--nav-4); }

/* ---- the confirmation, and its way out ----------------------------- */

/*
 * A FULL-WIDTH PRESS WITH AN ESCAPE BESIDE IT. The dangerous action takes
 * every pixel that is going, and the way out takes exactly the width of its
 * own word — so the two are never mistaken for a pair of equal choices, and
 * the pointer has nowhere to land between them.
 */
.confirm form { display: flex; }
.confirm form button { flex: 1; text-align: left; padding: 0.6rem 1.1rem; }
.confirm form a {
    display: flex;
    align-items: center;
    padding: 0.6rem 1.1rem;
    background: var(--flat-3);
    color: var(--muted);
    text-decoration: none;
    white-space: nowrap;
}
.confirm form a:hover { background: var(--flat-4); }

/* The confirmation's own inputs sit flush inside the band. */
/* -3: it is a control, and it must not vanish into the -2 band around it. */
.confirm input[type="text"] { background: var(--no-3); }

/* ---- forms --------------------------------------------------------- */

/*
 * ONE FIELD IS ONE COLOUR, IN TWO STEPS. The label sits on the deeper shade
 * and the input on the lighter one, so the pair reads as one object without a
 * box round it — which is what the border used to do and what removing the
 * spacing took away. The steps are small on purpose: far enough apart to
 * group, near enough not to look like two different things.
 */
form.create { display: block; }
/*
 * THE BLOCK'S OWN SHADES DO THE WORK INSIDE IT: label on -1, the field's row
 * on -2, the input you type into on -3. Three steps of one colour, which is
 * what tells you these belong together now that nothing is spaced apart.
 */
form.create p     { margin: 0; padding: 0; background: var(--nav-2); }
form.create label { display: block; padding: 0.3rem 1.1rem; background: var(--nav-1); }
form.create input[type="text"],
form.create input[type="email"] { background: var(--nav-3); }
form.create small { display: block; padding: 0.2rem 1.1rem 0.5rem; }

input[type="email"], input[type="text"] {
    font: inherit;
    border: 0;
    padding: 0.4rem 1.1rem;
    width: 100%;
    background: transparent;
    color: var(--ink);
}
input:focus-visible { outline: 2px solid var(--nav); outline-offset: -2px; }

label { display: block; }
label input[type="checkbox"] { margin-right: 0.4rem; }

/*
 * BLUE, LIKE THE BLOCK IT ENDS. An earlier version made this green on the
 * argument that an action's colour should say what a press will do regardless
 * of where it sits — which is sound, and was overruled for a better reason:
 * green was already carrying approve, unblock and house, and a fourth green
 * button dilutes the three that need to be noticed.
 *
 * It also makes the rule simpler than the exception did. A block that takes a
 * hue takes it THROUGHOUT, and the four shades do the work inside it — which
 * is what a whole-block colour was for.
 */
form.create > button {
    display: block;
    width: 100%;
    text-align: left;
    padding: 0.6rem 1.1rem;
    background: var(--nav-3);
}
form.create > button:hover { background: var(--nav-4); }
