/*
 * Element defaults and the base components.
 *
 * Everything here reads tokens.css; no literal colour, size or radius below.
 * The components are the six the whole app is built from -- button, field,
 * card, pill, alert, table -- plus the shell for the three screens you can
 * reach without logging in. Chapter-specific pieces (the bottom sheet and
 * stepper in chapter 6, the data-table variants in chapter 7) stay in their
 * chapter.
 *
 * Rendered in every state at /_components in dev.
 */

/* ---- Elements ----------------------------------------------------------- */

*,
*::before,
*::after {
    box-sizing: border-box;
}

body {
    margin: 0;
    background: var(--surface-sunken);
    color: var(--text);
    font: var(--weight-regular) var(--text-base) / 1.5 var(--font);
    /* Raleway's default figures are old-style: a 3 and a 7 drop below the
       line. A time-tracking app reads numbers all day; it wants them level. */
    font-variant-numeric: lining-nums;
    -webkit-text-size-adjust: 100%;
}

h1,
h2,
h3 {
    margin: 0;
    font-family: var(--font-heading);
    font-size: var(--text-lg);
    font-weight: var(--weight-bold);
    line-height: 1.25;
}

p {
    margin: 0;
}

a {
    color: var(--accent);
    font-weight: var(--weight-bold);
}

/*
 * The hidden attribute always wins. The browser's own [hidden] rule loses to
 * any author display -- a .btn's inline-flex, a grid -- so without this the
 * painter's "Weggooien" stood on every line, and each new component would
 * need its own [hidden] exception.
 */
[hidden] {
    display: none !important;
}

/*
 * Read by a screen reader, not drawn: the label of a field whose purpose the
 * row around it already shows, such as the name box in a table row.
 */
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

/*
 * One focus treatment everywhere, and a visible one. Gloves and sunlight make a
 * subtle ring useless, and keyboard users in the office need it to be obvious.
 */
:focus-visible {
    outline: 3px solid var(--focus-ring);
    outline-offset: 2px;
}

/* ---- Button ------------------------------------------------------------- */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    min-height: var(--tap-min);
    padding: 0 var(--space-4);
    border: var(--border-width) solid transparent;
    border-radius: var(--radius-button);
    background: none;
    font: inherit;
    font-weight: var(--weight-bold);
    text-align: center;
    text-decoration: none;
    cursor: pointer;
}

.btn--primary {
    background: var(--primary);
    color: var(--text-on-primary);
}

.btn--primary:hover {
    background: var(--primary-hover);
}

.btn--secondary {
    border-color: var(--border-strong);
    background: var(--surface);
    color: var(--text);
}

.btn--secondary:hover {
    background: var(--surface-sunken);
}

/*
 * Full width and 56px tall: the handoff's size for a primary action on the
 * painter's screen. A modifier rather than the default, because the office puts
 * several buttons side by side on one header row.
 */
.btn--block {
    width: 100%;
    min-height: var(--tap-primary);
}

/*
 * "Dag opslaan" is disabled until the day has at least one line, so this state
 * is on screen a lot. It stays readable: a greyed-out button nobody can read in
 * sunlight is a button nobody understands.
 */
.btn:disabled,
.btn[aria-disabled="true"] {
    border-color: var(--border);
    background: var(--state-empty-surface);
    color: var(--text-muted);
    cursor: not-allowed;
}

/* ---- Field -------------------------------------------------------------- */

.field {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}

.field__label {
    font-weight: var(--weight-bold);
}

.field__control {
    width: 100%;
    min-height: var(--tap-min);
    padding: var(--space-2) var(--space-3);
    border: var(--border-width) solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface);
    color: var(--text);
    font: inherit;
}

/*
 * A computed value shown in a form -- 2g's "Gewerkte uren — berekend". Flat
 * and dashed like an empty state, so it reads as not editable, while the text
 * keeps the muted token's 7:1.
 */
.field__control:disabled {
    border-style: dashed;
    background: var(--state-empty-surface);
    color: var(--text-muted);
    cursor: not-allowed;
}

/* Not light grey, because a hint has to be legible in sunlight too. */
.field__control::placeholder {
    color: var(--text-muted);
}

.field__help {
    color: var(--text-muted);
    font-size: var(--text-sm);
}

/*
 * The error state from handoff 1a and 2e: a heavier, darker border on the field
 * plus a line under it. Colour is never the only carrier -- the border weight
 * changes too, which survives both sunlight and colour blindness.
 */
.field--invalid .field__control {
    border-color: var(--border-strong);
    border-width: var(--border-width-strong);
}

.field__error {
    color: var(--state-error-text);
    font-size: var(--text-sm);
    font-weight: var(--weight-bold);
}

.field__error-list {
    margin: 0;
    padding: 0;
    list-style: none;
}

/* ---- Card --------------------------------------------------------------- */

.card {
    padding: var(--space-4);
    border: var(--border-width) solid var(--border);
    border-radius: var(--radius-md);
    background: var(--surface);
}

.card__title {
    margin-bottom: var(--space-3);
}

/* The empty state of a day or a week: present, but plainly not filled in. */
.card--empty {
    border-style: dashed;
    background: var(--state-empty-surface);
}

/* ---- Pill --------------------------------------------------------------- */

.pill {
    display: inline-flex;
    align-items: center;
    padding: var(--space-1) var(--space-3);
    border-radius: var(--radius-md);
    background: var(--state-empty-surface);
    color: var(--state-empty-text);
    font-size: var(--text-sm);
    font-weight: var(--weight-bold);
    white-space: nowrap;
}

.pill--complete {
    background: var(--state-complete-surface);
    color: var(--state-complete-text);
}

.pill--incomplete {
    background: var(--state-incomplete-surface);
    color: var(--state-incomplete-text);
}

.pill--empty {
    background: var(--state-empty-surface);
    color: var(--state-empty-text);
}

.pill--locked {
    background: var(--state-locked-surface);
    color: var(--state-locked-text);
}

/* ---- Alert -------------------------------------------------------------- */

.alert {
    padding: var(--space-3);
    border-radius: var(--radius-sm);
    font-weight: var(--weight-bold);
}

.alert--error {
    background: var(--state-error-surface);
    color: var(--state-error-text);
}

.alert--success {
    background: var(--state-complete-surface);
    color: var(--state-complete-text);
}

.alert--locked {
    background: var(--state-locked-surface);
    color: var(--state-locked-text);
}

/* ---- Table -------------------------------------------------------------- */

/*
 * The office's tables only. The painter never sees one: everything on a phone
 * is a card.
 */
.table-shell {
    overflow-x: auto;
    border: var(--border-width) solid var(--border);
    border-radius: var(--radius-md);
    background: var(--surface);
}

.table {
    width: 100%;
    border-collapse: collapse;
}

.table th,
.table td {
    padding: var(--space-3);
    border-bottom: var(--border-width) solid var(--border);
    text-align: left;
}

.table th {
    font-size: var(--text-sm);
    font-weight: var(--weight-bold);
}

.table tbody tr:last-child td {
    border-bottom: 0;
}

/* Amounts line up on the decimal comma, which is the point of a column. */
.table .is-numeric {
    font-family: var(--font-numeric);
    font-variant-numeric: tabular-nums;
    text-align: right;
}

/*
 * An inactive customer or a departed employee: "blijven leesbaar maar grijzer"
 * (handoff 2d). Grijzer here is the muted text token, which still clears 7:1 --
 * not a light grey.
 */
.table .is-inactive td {
    color: var(--text-muted);
}

/* ---- The signed-out shell ----------------------------------------------- */

.auth {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 100dvh;
    padding: var(--space-5) var(--gutter);
}

.auth__panel {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
    width: 100%;
    max-width: var(--painter-width);
}

/*
 * The dark ("dia") version of the client's logo, made for a light ground, so it
 * stands on the page itself. The cream original is for dark grounds only -- the
 * home-screen icons.
 */
.auth__logo {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 160px;
    margin: 0 auto;
}

.auth__logo img {
    display: block;
    width: 100%;
    height: auto;
}

.auth__title {
    text-align: center;
}

.auth__form {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
}

.auth__aside {
    text-align: center;
}
