/*
 * Studio styles on top of Bootstrap 5.3.3.
 *
 * Everything lives here rather than in style="" attributes: the CSP sets
 * style-src 'self' with no 'unsafe-inline', so an inline style attribute is
 * silently dropped by the browser. That constraint is deliberate and it holds
 * for the booklet preview too, where the geometry is an enumerated set of
 * layout variants rather than arbitrary per-element positioning.
 */

:root {
    --oaka-shell-max: 1600px;
}

/*
 * Oaka brand palette, replacing Bootstrap's default blue/grey/green/red.
 *
 * Bootstrap 5.3's compiled CSS does NOT read --bs-primary etc. at the point
 * of use — Sass bakes each component's colours into its OWN custom
 * properties (.btn-primary's --bs-btn-bg, .alert-success's --bs-alert-bg, …)
 * as literal hex, computed at build time. Only a handful of utility classes
 * (bg-*, text-*, border-*, plain links) read the root --bs-*-rgb variables
 * live. So retinting means redeclaring both: the root variables below for
 * those utilities, and the same per-component variables Bootstrap itself
 * would have generated for buttons and alerts, further down.
 *
 * Hover/active button shades are each colour mixed toward black by ~15%/20%,
 * matching how Bootstrap darkens its own default palette for those states.
 *
 * The lime (#95c11e) is too light for white text or thin borders — as
 * white-on-lime or lime-on-white it measures ~2.1:1, well under WCAG's 4.5:1
 * for body text. It stays the bright brand accent for solid fills (paired
 * with dark text) and the alert tint, but success TEXT and OUTLINE strokes
 * use a darker olive shade of it instead, the same way Bootstrap's own
 * alert text is a shade of success rather than the raw theme colour.
 */
:root {
    --bs-primary: #4a0492;
    --bs-primary-rgb: 74, 4, 146;
    --bs-secondary: #29016d;
    --bs-secondary-rgb: 41, 1, 109;
    --bs-success: #95c11e;
    --bs-success-rgb: 149, 193, 30;
    --bs-danger: #ec018c;
    --bs-danger-rgb: 236, 1, 140;

    --bs-link-color: #4a0492;
    --bs-link-color-rgb: 74, 4, 146;
    --bs-link-hover-color: #3f037c;
    --bs-link-hover-color-rgb: 63, 3, 124;

    --bs-primary-text-emphasis: #1e023a;
    --bs-primary-bg-subtle: #dbcde9;
    --bs-primary-border-subtle: #b79bd3;
    --bs-secondary-text-emphasis: #10002c;
    --bs-secondary-bg-subtle: #dfd9e9;
    --bs-secondary-border-subtle: #b4a6cc;
    --bs-success-text-emphasis: #2d3a09;
    --bs-success-bg-subtle: #eff6dd;
    --bs-success-border-subtle: #dae9b0;
    --bs-danger-text-emphasis: #5e0038;
    --bs-danger-bg-subtle: #fcd9ee;
    --bs-danger-border-subtle: #f8a6d7;
}

.btn-primary {
    --bs-btn-bg: #4a0492;
    --bs-btn-border-color: #4a0492;
    --bs-btn-hover-bg: #3f037c;
    --bs-btn-hover-border-color: #3b0375;
    --bs-btn-active-bg: #3b0375;
    --bs-btn-active-border-color: #370370;
    --bs-btn-disabled-bg: #4a0492;
    --bs-btn-disabled-border-color: #4a0492;
    --bs-btn-focus-shadow-rgb: 74, 4, 146;
}

.btn-outline-primary {
    --bs-btn-color: #4a0492;
    --bs-btn-border-color: #4a0492;
    --bs-btn-hover-bg: #4a0492;
    --bs-btn-hover-border-color: #4a0492;
    --bs-btn-active-bg: #4a0492;
    --bs-btn-active-border-color: #4a0492;
    --bs-btn-disabled-color: #4a0492;
    --bs-btn-disabled-border-color: #4a0492;
    --bs-btn-focus-shadow-rgb: 74, 4, 146;
}

.btn-secondary {
    --bs-btn-bg: #29016d;
    --bs-btn-border-color: #29016d;
    --bs-btn-hover-bg: #23015d;
    --bs-btn-hover-border-color: #210157;
    --bs-btn-active-bg: #210157;
    --bs-btn-active-border-color: #1e0150;
    --bs-btn-disabled-bg: #29016d;
    --bs-btn-disabled-border-color: #29016d;
    --bs-btn-focus-shadow-rgb: 41, 1, 109;
}

.btn-outline-secondary {
    --bs-btn-color: #29016d;
    --bs-btn-border-color: #29016d;
    --bs-btn-hover-bg: #29016d;
    --bs-btn-hover-border-color: #29016d;
    --bs-btn-active-bg: #29016d;
    --bs-btn-active-border-color: #29016d;
    --bs-btn-disabled-color: #29016d;
    --bs-btn-disabled-border-color: #29016d;
    --bs-btn-focus-shadow-rgb: 41, 1, 109;
}

.btn-success {
    --bs-btn-color: #1a1a1a;
    --bs-btn-bg: #95c11e;
    --bs-btn-border-color: #95c11e;
    --bs-btn-hover-color: #1a1a1a;
    --bs-btn-hover-bg: #7fa41a;
    --bs-btn-hover-border-color: #779a18;
    --bs-btn-active-color: #1a1a1a;
    --bs-btn-active-bg: #779a18;
    --bs-btn-active-border-color: #6f9017;
    --bs-btn-disabled-color: #1a1a1a;
    --bs-btn-disabled-bg: #95c11e;
    --bs-btn-disabled-border-color: #95c11e;
    --bs-btn-focus-shadow-rgb: 149, 193, 30;
}

.btn-outline-success {
    --bs-btn-color: #2d3a09;
    --bs-btn-border-color: #2d3a09;
    --bs-btn-hover-color: #1a1a1a;
    --bs-btn-hover-bg: #95c11e;
    --bs-btn-hover-border-color: #95c11e;
    --bs-btn-active-color: #1a1a1a;
    --bs-btn-active-bg: #95c11e;
    --bs-btn-active-border-color: #95c11e;
    --bs-btn-disabled-color: #2d3a09;
    --bs-btn-disabled-border-color: #2d3a09;
    --bs-btn-focus-shadow-rgb: 149, 193, 30;
}

.btn-danger {
    --bs-btn-bg: #ec018c;
    --bs-btn-border-color: #ec018c;
    --bs-btn-hover-bg: #c90177;
    --bs-btn-hover-border-color: #bd0170;
    --bs-btn-active-bg: #bd0170;
    --bs-btn-active-border-color: #b10169;
    --bs-btn-disabled-bg: #ec018c;
    --bs-btn-disabled-border-color: #ec018c;
    --bs-btn-focus-shadow-rgb: 236, 1, 140;
}

.btn-outline-danger {
    --bs-btn-color: #ec018c;
    --bs-btn-border-color: #ec018c;
    --bs-btn-hover-bg: #ec018c;
    --bs-btn-hover-border-color: #ec018c;
    --bs-btn-active-bg: #ec018c;
    --bs-btn-active-border-color: #ec018c;
    --bs-btn-disabled-color: #ec018c;
    --bs-btn-disabled-border-color: #ec018c;
    --bs-btn-focus-shadow-rgb: 236, 1, 140;
}

/* .text-bg-success is otherwise white-on-lime — see the contrast note above. */
.text-bg-success {
    color: #1a1a1a !important;
}

.form-control:focus,
.form-select:focus {
    border-color: #9b75c3;
    box-shadow: 0 0 0 .25rem rgba(74, 4, 146, .25);
}

body {
    -webkit-font-smoothing: antialiased;
}

main {
    max-width: var(--oaka-shell-max);
    margin-inline: auto;
}

/* Status list on the landing page. */
.list-group-item .badge {
    min-width: 4.5rem;
}

/*
 * Artwork queue.
 *
 * The thumbnail is a confirmation that the right file landed, not a proof — so
 * it is small and fixed. Left to itself an img-thumbnail takes the width of its
 * column, and a print illustration rendered at 600px dominated the card.
 */
.artwork-thumb {
    width: 96px;
    height: auto;
    flex-shrink: 0;
}

/*
 * "In the Image Library" — the perceptual-match strip under an upload
 * reference on the Artwork Queue (see ref-library-matches.php).
 *
 * Deliberately smaller than the reference thumbnail above it: this is a
 * pointer ("go look at this instead of redrawing it"), not the reference
 * itself, and a queue with three references times up to four matches each
 * would otherwise be mostly match thumbnails. `text-decoration: none` on the
 * link because Bootstrap's default underline reads oddly across an image and
 * two stacked lines of text; the filename keeps its own truncation instead.
 *
 * `.ref-library-match` is the outer column (fixed width, so the strip wraps
 * predictably); `.ref-library-match-link` is just the part that opens the
 * library in a new tab. They used to be the same element, but "Use as
 * artwork" needed a second, separately-clickable thing — a <button> — inside
 * the same 72px column, below the link rather than inside it.
 */
.ref-library-matches-heading {
    margin-top: 0.25rem;
}

.ref-library-match {
    width: 72px;
}

.ref-library-match-link {
    display: block;
    color: inherit;
    text-decoration: none;
}

.ref-library-match-thumb {
    display: block;
    width: 72px;
    height: 72px;
    object-fit: contain;
    background-color: var(--bs-tertiary-bg);
    border: 1px solid var(--bs-border-color);
    border-radius: 0.25rem;
}

.ref-library-match-badge {
    display: block;
    width: 100%;
    margin-top: 0.15rem;
    font-size: 0.65rem;
    white-space: normal;
}

.ref-library-match-name {
    display: block;
    margin-top: 0.1rem;
}

/*
 * "Use as artwork" — a full-size Bootstrap .btn-sm is taller and wider than
 * this 72px column has room for next to three other matches. Sized down
 * further rather than reused as-is; `width: 100%` so it lines up under the
 * thumbnail instead of sizing to its own text.
 */
.ref-library-match-use-form {
    margin-top: 0.25rem;
}

.ref-library-match-use {
    display: block;
    width: 100%;
    padding: 0.1rem 0.25rem;
    font-size: 0.65rem;
    line-height: 1.2;
}

/*
 * Storage paths are long, contain slashes, and have no spaces to break at, so
 * they overflow their container and run off the page. `anywhere` lets the
 * browser break mid-token; `min-w-0` on the flex child is what actually allows
 * the shrink, since a flex item's default min-width is its content.
 */
.artwork-path {
    display: block;
    overflow-wrap: anywhere;
    word-break: break-word;
}

/*
 * The near-duplicate choice queue.js draws on a refused upload (see
 * ArtworkUpload::storeAs()'s `duplicate` payload) — small, because it is a
 * "is this the same picture?" confirmation next to the upload form, not the
 * reference itself.
 */
.artwork-duplicate-thumb {
    width: 48px;
    height: 48px;
    object-fit: cover;
    flex-shrink: 0;
}

.min-w-0 {
    min-width: 0;
}

/*
 * Reference thumbnails in the editors.
 *
 * A reference is a reminder of what the author picked, not something to study,
 * and the brief column is wide — in the glossary a reference was rendering
 * several hundred pixels across and pushing the term's row taller than the rest
 * of the table. Capped at 200 px in BOTH directions: a cap can only ever shrink
 * a picture, so the page editor gets the same rule without needing its own.
 *
 * `card-img-top` sets width:100%, so width has to be handed back to the image
 * before max-width can do anything; object-fit keeps the aspect ratio when a
 * tall reference hits the height cap instead of the width one.
 *
 * The artwork queue is deliberately NOT included. The designer is working from
 * those references rather than glancing at them, and bigger is better there.
 */
[data-role="refs"] .card {
    max-width: 200px;
}

[data-role="refs"] .card-img-top {
    display: block;
    width: auto;
    height: auto;
    max-width: 200px;
    max-height: 200px;
    margin-inline: auto;
    object-fit: contain;
}

/*
 * Drop feedback on the pack organiser.
 *
 * Drawn with an inset box-shadow rather than a border, because a border adds
 * to an element's size: with `border-3` the booklet twitched every time the
 * pointer crossed a box, and on a long page that reads as the whole screen
 * juddering under the drag.
 *
 * `.drop-onto` outlines the thing the dragged box would trade places with —
 * a box, or a whole page card. `.drop-before` is a line along the top edge of
 * the box the dragged one would land in FRONT of, which is the same place the
 * insertion point will be once the drop is applied.
 *
 * Kept apart from the classes that mark a SELECTED box (see
 * pack-organiser.js) so that clearing drop feedback between dragover events
 * cannot strip the highlight off boxes the author has picked out.
 */
.drop-onto {
    box-shadow: inset 0 0 0 3px var(--bs-primary);
}

.drop-before {
    box-shadow: inset 0 3px 0 0 var(--bs-primary);
}

/*
 * Textareas that grow with their text — the glossary's term, phonetic,
 * definition and brief fields. glossary.js sets the height from the content
 * on load and on every keystroke, so the box itself must not fight that: no
 * scrollbar (the script keeps the content in view, and a scrollbar's width
 * would alter the wrap it just measured) and no drag handle, which would
 * only be undone on the next keystroke.
 */
textarea[data-autogrow] {
    overflow-y: hidden;
    resize: none;
}

/*
 * The box body editor.
 *
 * A contenteditable that has to look like a form field, because it sits in a
 * card next to real ones — `.form-control` supplies the border, radius and
 * focus ring, and the rules here supply what it cannot: a sensible minimum
 * height, and lists that indent the way the printed booklet's do.
 *
 * `min-height` rather than `rows`: a box body is a few lines and the field
 * should grow with it rather than scroll, which is what the old per-bullet
 * textareas got wrong — a long paragraph hid its own last line.
 */
.box-body-editor {
    min-height: 6.5rem;
    height: auto;
    overflow-wrap: break-word;
}

.box-body-editor > :last-child {
    margin-bottom: 0;
}

.box-body-editor p {
    margin-bottom: 0.5rem;
}

.box-body-editor ul,
.box-body-editor ol {
    margin-bottom: 0.5rem;
    padding-left: 1.5rem;
}

/*
 * The two marks, drawn at the weight they actually carry.
 *
 * A key term is set in `Oaka Key Term`, which the deriver builds as plain
 * bold — the same thing `Oaka Bold` is. So a key term PRINTS as bold and
 * nothing more, and the editor draws it as bold and nothing more, in the
 * brand purple to say it is tagged rather than merely emphasised.
 *
 * It is deliberately not highlighted. An earlier version of this rule gave
 * every key term a filled background, which looked like a page full of
 * errors: this pack alone holds 1020 of them, 821 of which do not match any
 * glossary term — they are emphasis the HTML import tagged as `key` on the
 * assumption that a bold word inside a sentence was a term. Shouting about
 * 1020 runs that print as ordinary bold tells the author nothing.
 *
 * The highlight belongs to `[data-wyon]`, which is rare (8 runs, against
 * those 1020) and is the only mark that changes what a pupil sees — the word
 * is gone from the Write Your Own Notes edition. That is worth a background
 * and a dashed underline; a key term is not.
 */
.box-body-editor [data-mark="key"] {
    font-weight: 700;
    color: var(--bs-primary);
}

.box-body-editor [data-wyon="1"] {
    background-color: var(--bs-primary-bg-subtle);
    border-radius: 0.2rem;
    padding: 0 0.15em;
    text-decoration: underline;
    text-decoration-style: dashed;
    text-underline-offset: 0.2em;
}

/*
 * Italic is what `Oaka Phonetic` sets, so italic is what the editor shows.
 * The muted colour is the only editor-only part, and it stays muted: a
 * pronunciation guide is an aside, and drawing it louder than the sentence it
 * explains would misrepresent the page.
 */
.box-body-editor [data-mark="phon"] {
    font-style: italic;
    color: var(--bs-secondary-color);
}

/*
 * The publish review (packs/publish.php): the pack's artwork beside the
 * Library image it resembles, small enough that a 150-item pack stays one
 * scrollable table.
 */
.publish-thumb {
    width: 56px;
    height: 56px;
    object-fit: contain;
    background-color: var(--bs-tertiary-bg);
    flex-shrink: 0;
}

.publish-table td {
    max-width: 22rem;
}
