/* File: css/utilities.css
 *
 * ── WHY THIS FILE EXISTS ─────────────────────────────────────────────────────
 * It replaces `<script src="https://cdn.tailwindcss.com">`, which used to sit in
 * the <head> of index.html.
 *
 * That script was a browser-side Tailwind COMPILER — ~400 KB of JavaScript that
 * scanned the DOM on every load and generated a stylesheet at runtime. Tailwind's
 * own documentation says not to ship it to production. In this application it was
 * worse than merely slow, because the app is offline-first:
 *
 *   * `service-worker.js` deliberately does not cache cross-origin requests, so
 *     the CDN was protected only by the browser's HTTP cache;
 *   * that cache entry carried `max-age=14400` — FOUR HOURS. A tablet opened the
 *     next morning with no signal had an expired entry it could not revalidate;
 *   * with the stylesheet gone, `grid-template-columns` resolved to `none` and
 *     every dashboard grid collapsed into a single column.
 *
 * A 400 KB runtime compiler for the three dozen rules below was a bad trade even
 * before the offline problem.
 *
 * ── WHY IT IS LINKED LAST, AND WHY IT REDEFINES CLASSES THAT ALREADY EXIST ───
 * The CDN appended its <style> element to <head> at runtime, so its rules landed
 * AFTER every <link> stylesheet and won every same-specificity tie.
 *
 * That is why this file does not contain only the classes design-system.css was
 * missing. Many utilities are defined in BOTH places with different values —
 * `.text-lg` resolved to a 28px line-height from Tailwind and 22.5px from
 * design-system.css; `.mb-4` to 16px and 20px — and Tailwind was winning every
 * one. Reimplementing only the gaps therefore restyled the app rather than
 * preserving it: the first attempt at this file moved 193 elements.
 *
 * So: every utility class index.html uses is written out here, at Tailwind's
 * value, in the cascade position Tailwind occupied. Preflight first, utilities
 * after, exactly as Tailwind emits them.
 *
 * Verified by diffing the computed styles of all 1352 elements on the page,
 * before and after the swap.
 */

/* ============================================================================
   1. PREFLIGHT
   The subset of Tailwind's base reset that this application actually depends on.
   design-system.css already resets box-sizing, margin and padding, so what
   remains is the border reset and the list reset — both load-bearing:

     * `border-width: 0` + `border-style: solid` + `border-color: #e5e7eb` is why
       elements here can set a border WIDTH and get a visible grey line without
       naming a colour. Drop it and those borders fall back to `currentColor`,
       which is the text colour.
     * `list-style: none` on ol/ul is why no list in this UI shows a bullet.
   ============================================================================ */

*,
::before,
::after {
    border-width: 0;
    border-style: solid;
    border-color: #e5e7eb;
}

html {
    line-height: 1.5;
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
    tab-size: 4;
    font-family: ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji',
        'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
}

ol,
ul,
menu {
    list-style: none;
}

/* Headings inherit their size and weight; every heading in this UI is styled by
   a component rule, and a bare <h1> must not fall back to the UA's 2em/bold. */
h1,
h2,
h3,
h4,
h5,
h6 {
    font-size: inherit;
    font-weight: inherit;
}

/* Form controls inherit typography rather than using the UA's 13.33px default. */
button,
input,
optgroup,
select,
textarea {
    font-family: inherit;
    font-size: 100%;
    font-weight: inherit;
    line-height: inherit;
    color: inherit;
}

button,
select {
    text-transform: none;
}

/* :where() ramène ces sélecteurs d'attribut à une spécificité nulle. Sans lui,
   [type='submit'] (0,1,0) fait égalité avec toute règle à une classe comme
   .login-btn et gagne par ordre de chargement — ce fichier étant dernier —,
   effaçant le dégradé du bouton au repos alors que son :hover (0,2,0) survit :
   un bouton blanc qui ne devient vert qu'au survol. Le reset ne doit gagner
   que contre les styles du navigateur, jamais contre une règle écrite ici. */
button,
:where([type='button'], [type='reset'], [type='submit']) {
    -webkit-appearance: button;
    background-image: none;
}

button,
[role='button'] {
    cursor: pointer;
}

:disabled {
    cursor: default;
}

img,
svg,
video,
canvas,
audio,
iframe,
embed,
object {
    display: block;
    vertical-align: middle;
}

img,
video {
    max-width: 100%;
    height: auto;
}

textarea {
    resize: vertical;
}

input::placeholder,
textarea::placeholder {
    opacity: 1;
    color: #9ca3af;
}

[hidden] {
    display: none;
}

/* ============================================================================
   2. UTILITIES
   Every Tailwind class index.html uses, at Tailwind's own value.

   Classes design-system.css also defines are repeated here ON PURPOSE — see the
   file header. This file is last, so these are the values that win, which is what
   was true while the CDN was loaded.

   NOT DEFINED, DELIBERATELY: `text-md`. index.html uses it, but Tailwind has no
   such class — the scale is text-sm / text-base / text-lg. It has therefore never
   matched a rule and has always been inert. Giving it a size here would change
   the design rather than preserve it.

   NOT DEFINED, DELIBERATELY: `animate-pulse`. design-system.css:352 has its own
   `pulse` animation and keeps it. Tailwind's differs only in timing function.
   ============================================================================ */

/* Display */
.flex   { display: flex; }
.grid   { display: grid; }
.hidden { display: none; }

/* Flex & grid */
.flex-1    { flex: 1 1 0%; }
.flex-wrap { flex-wrap: wrap; }

.items-center    { align-items: center; }
.items-end       { align-items: flex-end; }
.justify-center  { justify-content: center; }
.justify-between { justify-content: space-between; }
.justify-end     { justify-content: flex-end; }

.gap-1 { gap: 0.25rem; }
.gap-2 { gap: 0.5rem; }
.gap-4 { gap: 1rem; }

.grid-cols-1 { grid-template-columns: repeat(1, minmax(0, 1fr)); }

/* Tailwind's default breakpoints: md = 768px, lg = 1024px. */
@media (min-width: 768px) {
    .md\:grid-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (min-width: 1024px) {
    .lg\:grid-cols-5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }
}

/* Sizing */
.h-2  { height: 0.5rem; }
.h-10 { height: 2.5rem; }
.w-2  { width: 0.5rem; }
.min-h-\[300px\] { min-height: 300px; }

/* Spacing */
.p-4  { padding: 1rem; }
.pt-4 { padding-top: 1rem; }
.py-2 { padding-top: 0.5rem; padding-bottom: 0.5rem; }
.py-4 { padding-top: 1rem;   padding-bottom: 1rem; }
.py-8 { padding-top: 2rem;   padding-bottom: 2rem; }

.mt-1 { margin-top: 0.25rem; }
.mt-2 { margin-top: 0.5rem; }
.mt-4 { margin-top: 1rem; }
.mb-2 { margin-bottom: 0.5rem; }
.mb-4 { margin-bottom: 1rem; }
.mb-6 { margin-bottom: 1.5rem; }

/* Typography. The line-heights are the part that matters: font sizes here match
   design-system.css already, but its line-heights do not (`.text-lg` resolved to
   22.5px there against Tailwind's 28px). */
.text-xs { font-size: 0.75rem;  line-height: 1rem; }
.text-sm { font-size: 0.875rem; line-height: 1.25rem; }
.text-lg { font-size: 1.125rem; line-height: 1.75rem; }

.font-medium   { font-weight: 500; }
.font-semibold { font-weight: 600; }

.text-center { text-align: center; }
.text-right  { text-align: right; }

/* Borders */
.border          { border-width: 1px; }
.border-gray-200 { border-color: #e5e7eb; }

.rounded-lg   { border-radius: 0.5rem; }
.rounded-full { border-radius: 9999px; }

/* Colour */
.bg-gray-50    { background-color: #f9fafb; }
.bg-green-500  { background-color: #22c55e; }
.bg-yellow-500 { background-color: #eab308; }
