/* SchoolCMS – Content tables
   Base styling for WYSIWYG content (js/utilities/table.js wraps bare
   tables in Bootstrap's .table-responsive), plus the three colour
   variants applied from the editor's Formats dropdown (inc/wysiwyg.php
   + js/admin/wysiwyg-table-styles.js). Restyle per site to the old site's tables,
   renaming the variant classes and dropdown titles to the site's colours.

   The house table (Charlie, 2026-11-04 – every site carries it, /setup
   builds it): the top row is a solid header in the colour the site's
   download links and FAQs use, with white titles, and the body rows
   alternate with a stripe of the header's colour – as strong as it
   takes to stand clear of the page, set per colour (below) – the
   first row under the header plain. A colour variant moves only the header's
   colour, and its rows stripe in that colour. Where a site's design
   already draws its header in a solid dark colour, that colour stays;
   where it draws visible borders – a grid, or rules between the rows –
   the borders stay and the table takes no stripes. The header's colour
   is --table-accent and its titles' --table-accent-text, both set on the
   table, so a variant's class overrides them. The scroll bar under a
   wide table takes the header's colour too (table.js). */

/* No frame round the table. The editor's Table button writes border="1"
   on every table it makes, and the browser draws that attribute as a 1px
   frame the design does not have – so a client-made table came out boxed
   where a hand-written one did not (found on Burlington, 2026-10-14).
   Bootstrap's reboot already cancels the cells' half of the attribute;
   `border: 0` here cancels the table's, so every table reads the same
   however it was made. The lines a wysiwyg adds to show the columns are
   css/admin/editor-canvas.css. */
table {
    --table-accent:      var(--color-black);
    --table-accent-text: var(--color-white);
    --table-stripe:      13%;

    width:           100%;
    margin:          var(--space-md) 0 var(--space-lg);
    border:          0;
    border-collapse: collapse;

    th,
    td {
        padding:        14px 24px;
        font:           var(--text-16or);
        color:          var(--color-black);
        text-align:     left;
        /* Rows are as tall as their longest cell; centring leaves the
           short cells floating against wrapped neighbours, so every cell
           starts at the top. */
        vertical-align: top;
    }

    /* The header row. TinyMCE's Table button builds every row out of
       <td>, so a table the client made by hand has no <th> at all; where
       there is no header cell anywhere, the first row stands in for one.
       And only the table's own first row, not the opening row of every
       section: a plain `tr:first-child` also matches the first row inside
       <tbody>, so a table split into <thead> + <tbody> would come out
       with two header rows – use the thead when there is one, the first
       tbody otherwise. (Both lessons inherited from the Cathedral build.) */
    th,
    &:not(:has(th)) > thead:first-of-type > tr:first-child > td,
    &:not(:has(th)):not(:has(thead)) > tbody:first-of-type > tr:first-child > td {
        padding:    20px 24px;
        font:       var(--text-20ob);
        color:      var(--table-accent-text);
        background: var(--table-accent);
    }

    /* Alternate body rows: a stripe of the header's colour, the first row
       under the header plain. Which rows those are depends on what the
       header is – a thead's row, so the tbody's even rows; or the table's
       own first row, so its 3rd, 5th, 7th… Keyed to --table-accent, so each
       colour variant stripes in its own colour, at the strength
       --table-stripe sets beside the colour: the share of it that stands
       the stripe ΔE 10 off the page, so every colour's rows are as easy
       to tell apart (Charlie, 2026-11-04 – a flat 8% left a light
       colour's stripes all but invisible). A dark header takes about 13%, a
       light one far more – .claude/scripts/stripe-mix.py works it out
       from the page's colour and the header's. */
    &:has(thead) > tbody > tr:nth-child(even) > td,
    &:not(:has(thead)) > tbody:first-of-type > tr:nth-child(2n+3) > td {
        background: color-mix(in srgb, var(--table-accent) var(--table-stripe), transparent);
    }
}

/* ── Colour variants (Formats dropdown – Black/Orange/Teal Table) ──
   The header carries the accent – the whole visible difference between
   the three, stripes included. Black restates the default, so an editor
   who applied another colour has a way back to it (CLAUDE.md: the
   default has to be one of the choices); it leads the dropdown. */
.table-black {
    --table-accent: var(--color-black);
    --table-stripe: 13%;
}

.table-orange {
    --table-accent: var(--color-orange);
    --table-stripe: 13%;
}

.table-teal {
    --table-accent:      var(--color-teal);
    /* teal is a light accent – white text would vanish on it */
    --table-accent-text: var(--color-black);
    --table-stripe:      42%;
}

/* The bar under a table wider than the page (js/utilities/table.js draws
   it). A phone and a Mac trackpad show the native scrollbar only while
   the table is being scrolled, so nothing said the table went on past the
   edge (Charlie, 2026-10-29, found on The Hall School). This one is in
   view whenever the table overflows: a 4px track in the table's ink at
   15%, the thumb – the visible share of the table – in the ink, 8 under
   the table (inside its margin). Drag the thumb or click the track.
   The ink is the table's own header colour, which table.js hands the
   bar and the wrapper as --table-scroll-ink, so a table in a colour
   variant gets a bar in that colour (Charlie, 2026-11-04, found on
   Burlington: four variants, one bar colour); a pale header gives its
   titles' colour instead, which stays visible. The black is the
   fallback for a bar the script has not reached.
   It takes no room: .tableScroll is an empty line after the wrapper and
   draws the track up into the space under the table, which table.js
   measures into --table-scroll-room – so nothing on the page moves when
   it appears, whatever margins the table has. The native bar is hidden
   only where the script has put this one in place, so without JS the
   table still scrolls with it. */
.table-responsive.has-scroll-bar {
    scrollbar-width: none;

    &::-webkit-scrollbar {
        display: none;
    }

    &:focus-visible {
        outline:        2px solid var(--table-scroll-ink, var(--color-black));
        outline-offset: 2px;
    }
}

.tableScroll {
    position:     relative;
    height:       0;
    cursor:       pointer;
    touch-action: none;

    &[hidden] {
        display: none;
    }

    /* the track and the thumb on one line, 8 under the table */
    &::before,
    .tableScrollThumb {
        position:      absolute;
        top:           calc(8px - var(--table-scroll-room, 0px));
        height:        4px;
        border-radius: 2px;
    }

    &::before {
        content:    '';
        left:       0;
        right:      0;
        background: color-mix(in srgb, var(--table-scroll-ink, var(--color-black)) 15%, transparent);
    }

    .tableScrollThumb {
        left:       0;
        background: var(--table-scroll-ink, var(--color-black));
        cursor:     grab;

        &.is-dragging {
            cursor: grabbing;
        }
    }
}

/* Room for a table's shadow. Bootstrap's .table-responsive scrolls
   sideways, and a box that scrolls one way clips both, so a header band
   with a shadow is sliced along its top and at both ends (Brakenmoor's
   embossed header, 2026-11-05). A site whose table casts one sets the
   reach – offset + 1.5 × blur, the shadow's tail – as --table-room-y and,
   sideways, half the phone gutter (--table-room-x): the wrapper's box
   grows by that much and an equal negative margin puts the table back,
   so nothing on the page moves. The house table casts none. */
.table-responsive:has(> table) {
    margin:  calc(-1 * var(--table-room-y, 0px)) calc(-1 * var(--table-room-x, 0px));
    padding: var(--table-room-y, 0px) var(--table-room-x, 0px);
}

/* The floor that makes the wrapper's sideways scroll actually happen:
   width: 100% alone lets a phone screen crush the columns to a word per
   line – the table never outgrows the wrapper, so overflow-x has nothing
   to do. Floors scale with the column count; a 2-column table fits any
   screen unaided. */
.table-responsive > table {
    &:has(tr > :nth-child(3)) {
        min-width: 640px;
    }

    &:has(tr > :nth-child(5)) {
        min-width: 900px;
    }
}
