/*
 * Shared controls for tool views.
 *
 * Tools should only use these classes, so restyling this one file restyles
 * every tool without any tool folder being touched. Nothing here may be
 * renamed or removed - eighteen tool stylesheets and their markup are built
 * on these exact names.
 *
 * Colour comes from tokens.css. Where a rule says var(--accent) it picks up
 * whatever the mounted tool set on the content root, so a tool's primary
 * button, focus ring and active segment adopt its identity for free.
 * var(--accent) is always the contrast-safe weight; var(--tool-accent) is the
 * raw manifest hue and is used for decoration only.
 */

.tool {
    display: flex;
    flex-direction: column;
    min-height: 100%;
    font-size: var(--fs-md);
    line-height: var(--lh);
    color: var(--ink);
}

/* Solid, not blurred: this bar sits still while a long table scrolls under it,
   and a live-blur compositing layer on that path was the single most expensive
   thing in the old shell. */
.tool__toolbar {
    position: sticky;
    top: 0;
    z-index: 5;
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    flex-wrap: wrap;
    padding: 9px var(--sp-4);
    background: var(--surface);
    border-bottom: 1px solid var(--line);
}

.tool__title { margin: 0; font-size: var(--fs-lg); font-weight: 800; letter-spacing: -0.01em; }
.tool__spacer { flex: 1; }
.tool__body { padding: var(--sp-4); }
.tool__grid { display: grid; gap: var(--sp-4); }
.tool__grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.tool__grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.tool__grid--sidebar { grid-template-columns: minmax(0, 1fr) 320px; align-items: start; }

/* The fixed 320px column cannot hold below this, and letters is the one tool
   that uses it. Stacking beats crushing the main column to nothing. */
@media (max-width: 1180px) {
    .tool__grid--sidebar { grid-template-columns: minmax(0, 1fr); }
}

/* ---- segmented tabs ----------------------------------------------------- */

.segment {
    display: inline-flex;
    padding: 2px;
    border-radius: var(--radius-sm);
    background: var(--panel);
    border: 1px solid var(--line);
}
.segment__btn {
    padding: 5px 14px;
    border: 0;
    border-radius: 4px;
    background: transparent;
    font-size: var(--fs-sm);
    font-weight: 700;
    color: var(--ink-2);
    transition: background var(--dur-fast) ease, color var(--dur-fast) ease;
}
.segment__btn:hover { color: var(--ink); }
.segment__btn.is-active {
    background: var(--surface);
    color: var(--ink);
    box-shadow: var(--shadow-1);
}

/* ---- cards ---------------------------------------------------------------
   A hairline and no shadow. Elevation is reserved for things that float over
   the page; a card is part of the page. */

.card {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    overflow: hidden;
}
.card__head {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    padding: 10px var(--sp-3);
    border-bottom: 1px solid var(--line);
    background: var(--panel);
}
.card__title { margin: 0; font-size: var(--fs-sm); font-weight: 800; color: var(--ink-2); }
.card__body { padding: var(--sp-3); }
.card__body--tight { padding: var(--sp-2); }
.card__tools { margin-bottom: var(--sp-2); }

/* ---- fields ------------------------------------------------------------- */

.field { display: flex; flex-direction: column; gap: 5px; margin-bottom: var(--sp-3); }
.field__label { font-size: var(--fs-sm); font-weight: 700; color: var(--ink-2); }
.field__hint { font-size: var(--fs-xs); color: var(--ink-3); line-height: 1.7; }
/* Moved out of glass.css, which the desktop never loaded: the datetools tool
   and the installer both set these and both rendered them unstyled. */
.field__hint.is-ok { color: var(--green-ink); font-weight: 700; }
.field__hint.is-bad { color: var(--red-ink); font-weight: 700; }

.input, .select, .textarea {
    width: 100%;
    padding: 8px 11px;
    border: 1px solid var(--line-2);
    border-radius: var(--radius-sm);
    background: var(--field);
    color: var(--ink);
    font-size: var(--fs-md);
    transition: border-color var(--dur-fast) ease, box-shadow var(--dur-fast) ease;
}
.input::placeholder, .textarea::placeholder { color: var(--ink-3); }
.input:hover, .select:hover, .textarea:hover { border-color: var(--ink-3); }
.input:focus, .select:focus, .textarea:focus {
    outline: 0;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--focus-ring);
}
.input--num { font-variant-numeric: tabular-nums; letter-spacing: 0.4px; }
.input--lg { padding: 11px 13px; font-size: var(--fs-lg); font-weight: 700; }
.textarea { min-height: 120px; resize: vertical; line-height: 1.9; }
.input[readonly], .textarea[readonly] {
    background: var(--panel);
    border-color: var(--line);
    color: var(--ink-2);
}
.input:disabled, .select:disabled, .textarea:disabled {
    background: var(--panel);
    border-color: var(--line);
    color: var(--ink-3);
    cursor: not-allowed;
}
.input--file { padding: 5px var(--sp-2); font-size: var(--fs-xs); }

.checkbox { display: flex; align-items: center; gap: var(--sp-2); font-size: var(--fs-sm); }
.checkbox input { width: 15px; height: 15px; accent-color: var(--accent); }
.checkbox--inline { display: inline-flex; align-items: center; gap: 5px; font-size: var(--fs-xs); }

.toolbar-field { display: inline-flex; align-items: center; gap: 6px; font-size: var(--fs-xs); color: var(--ink-2); }
.select--sm { padding: 4px var(--sp-2); font-size: var(--fs-xs); height: auto; }

/* ---- buttons ------------------------------------------------------------
   Accent variants darken with an inset overlay rather than a second hex,
   because the accent is written at runtime and no stylesheet can know what
   the mounted tool's hover colour should be. */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 7px 14px;
    border: 1px solid var(--line-2);
    border-radius: var(--radius-sm);
    background: var(--surface);
    font-size: var(--fs-sm);
    font-weight: 700;
    line-height: 1.4;
    color: var(--ink);
    white-space: nowrap;
    transition: background var(--dur-fast) ease, border-color var(--dur-fast) ease,
                box-shadow var(--dur-fast) ease, transform var(--dur-fast) ease;
}
.btn:hover { background: var(--hover-soft); }
.btn:active { transform: scale(0.98); }
.btn:disabled { opacity: 0.5; cursor: not-allowed; transform: none; }

.btn--primary {
    background: var(--accent);
    border-color: transparent;
    color: var(--accent-ink);
}
.btn--primary:hover { background: var(--accent); box-shadow: inset 0 0 0 999px rgba(0, 0, 0, 0.12); }

.btn--ghost {
    background: transparent;
    border-color: transparent;
    color: var(--accent);
}
.btn--ghost:hover { background: var(--accent-soft); }

.btn--danger { color: var(--red-ink); border-color: rgba(200, 64, 42, 0.35); }
.btn--danger:hover { background: var(--red-soft); }

.btn--sm { padding: 4px 9px; font-size: var(--fs-xs); }

/* ---- tables --------------------------------------------------------------
   Compact by design: ~32px rows at 12.5px, a sticky head, and a hover quiet
   enough to scan a long column without it flashing at you. */

.table { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); }
.table th, .table td {
    padding: 7px 10px;
    border-bottom: 1px solid var(--line);
    text-align: right;
    vertical-align: middle;
    line-height: 1.6;
}
.table th {
    background: var(--panel);
    font-weight: 800;
    color: var(--ink-2);
    white-space: nowrap;
    position: sticky;
    top: 0;
    z-index: 1;
}
.table tbody tr:hover { background: var(--hover-soft); }
.table td.num { font-variant-numeric: tabular-nums; white-space: nowrap; }
.table .input { padding: 4px var(--sp-2); font-size: var(--fs-sm); }
.table--rows td { border-bottom-color: var(--line); }

/* ---- badges ------------------------------------------------------------- */

.badge {
    display: inline-block;
    padding: 2px 9px;
    border-radius: var(--radius-pill);
    font-size: var(--fs-xs);
    font-weight: 700;
    background: var(--accent-soft);
    color: var(--accent);
}
.badge--green { background: var(--green-soft); color: var(--green-ink); }
.badge--amber { background: var(--amber-soft); color: var(--amber-ink); }
.badge--red { background: var(--red-soft); color: var(--red-ink); }
.badge--gray { background: var(--neutral-soft); color: var(--ink-2); }

/* ---- results / read-only values ---------------------------------------- */

.result {
    display: flex;
    flex-direction: column;
    gap: var(--sp-1);
    padding: 10px var(--sp-3);
    border-radius: var(--radius-sm);
    background: var(--panel);
    border: 1px solid var(--line);
}
.result__label { font-size: var(--fs-xs); color: var(--ink-3); font-weight: 700; }
.result__value { font-size: var(--fs-md); font-weight: 700; line-height: 1.85; word-break: break-word; }
.result__value--num { font-size: var(--fs-xl); font-variant-numeric: tabular-nums; letter-spacing: 0.5px; }
/* The tint carries the emphasis; a full-strength accent border around a large
   block reads as an error state rather than a highlight. */
.result--accent { background: var(--accent-soft); border-color: transparent; }

.empty { padding: 40px 20px; text-align: center; color: var(--ink-3); font-size: var(--fs-sm); }
.empty strong { display: block; margin-bottom: 6px; color: var(--ink-2); font-size: var(--fs-md); }

.divider { height: 1px; margin: var(--sp-4) 0; background: var(--line); border: 0; }

/* ---- key/value list -----------------------------------------------------
   A two-column <dl>. The class was already used by the settings "about" pane
   and the dashboard document panel but had never been defined anywhere, so
   both fell back to the browser default: every dt and dd on its own line with
   a 40px indent and no column alignment. */

.doc-kv {
    display: grid;
    grid-template-columns: minmax(120px, auto) minmax(0, 1fr);
    gap: 6px 14px;
    margin: 0;
    font-size: var(--fs-sm);
    line-height: 1.85;
}
.doc-kv dt { margin: 0; font-weight: 700; color: var(--ink-2); }
.doc-kv dd {
    margin: 0;
    min-width: 0;
    color: var(--ink);
    word-break: break-word;
    font-variant-numeric: tabular-nums;
}

.row { display: flex; align-items: center; gap: var(--sp-2); }
.row--between { justify-content: space-between; }
.row--wrap { flex-wrap: wrap; }

.totals { display: flex; flex-direction: column; gap: var(--sp-2); }
.totals__line { display: flex; justify-content: space-between; align-items: baseline; font-size: var(--fs-sm); }
.totals__line--grand {
    padding-top: 9px;
    border-top: 1px solid var(--line-2);
    font-size: var(--fs-lg);
    font-weight: 800;
}
.totals__value { font-variant-numeric: tabular-nums; }

/* ---- messages -------------------------------------------------------------
   Moved here from glass.css. Only the login page and the installer loaded that
   file, but tools/backup renders .alert inside the panel - where it had no
   styling at all. One home for it fixes that and keeps the contract in §3.2. */

.alert {
    margin-bottom: var(--sp-3);
    padding: 10px var(--sp-3);
    border-radius: var(--radius-sm);
    border: 1px solid transparent;
    font-size: var(--fs-sm);
    line-height: 1.85;
    color: var(--ink);
    text-align: right;
}
.alert--error { background: var(--red-soft); border-color: rgba(200, 64, 42, 0.32); }
.alert--ok    { background: var(--green-soft); border-color: rgba(46, 158, 91, 0.34); }
.alert--warn  { background: var(--amber-soft); border-color: rgba(197, 127, 22, 0.36); }
.alert--info  { background: var(--accent-soft); border-color: rgba(27, 59, 111, 0.28); }
.alert code {
    direction: ltr;
    display: inline-block;
    padding: 0 4px;
    border-radius: 4px;
    background: var(--neutral-soft);
}

/* ---- password strength meter ---------------------------------------------
   Also moved out of glass.css: tools/password and tools/settings both render
   it and both were unstyled inside the panel. */

.meter {
    display: block;
    height: 5px;
    margin: var(--sp-2) 0 5px;
    border-radius: 3px;
    background: var(--neutral-soft);
    overflow: hidden;
}
.meter__bar {
    display: block;
    height: 100%;
    width: 0;
    border-radius: 3px;
    background: var(--red);
    transition: width var(--dur-mid) ease, background var(--dur-mid) ease;
}
.meter__bar[data-level="2"] { background: var(--amber); }
.meter__bar[data-level="3"] { background: #9a9c33; }
.meter__bar[data-level="4"] { background: var(--green); }

/* ---- loading -------------------------------------------------------------
   The spinner is for an action inside a control ("saving…"). A view waiting
   for its content gets a skeleton in the shape of what is coming instead. */

.spinner {
    width: 20px; height: 20px;
    border-radius: 50%;
    border: 2.5px solid var(--line);
    border-top-color: var(--accent);
    animation: spin 700ms linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ---- toasts ---------------------------------------------------------------
   Moved out of desktop.css, which is deleted in phase 2. The stack that
   positions them belongs to the shell; a single toast is a shared component
   and every page that has a #toastStack gets the same one. */

.toast {
    display: flex;
    align-items: center;
    gap: 9px;
    max-width: 460px;
    padding: 9px 14px;
    border-radius: var(--radius-sm);
    font-size: var(--fs-sm);
    color: var(--ink);
    background: var(--surface);
    border: 1px solid var(--line);
    box-shadow: var(--shadow-2);
    animation: toast-in var(--dur-mid) var(--ease-out);
}
.toast::before {
    content: '';
    width: 8px; height: 8px;
    border-radius: 50%;
    background: var(--accent);
    flex: 0 0 auto;
}
.toast--success::before { background: var(--green); }
.toast--error::before { background: var(--red); }
.toast--warn::before { background: var(--amber); }
.toast.is-out { animation: toast-out 160ms var(--ease-mac) forwards; }

@keyframes toast-in { from { opacity: 0; transform: translateY(-8px); } to { opacity: 1; transform: none; } }
@keyframes toast-out { to { opacity: 0; transform: translateY(-6px); } }

/* ---- print -------------------------------------------------------------- */

.print-only { display: none; }

@media print {
    body > *:not(.print-host) { display: none !important; }
    .print-host { position: static !important; display: block !important; }
    .print-only { display: block; }
    @page { size: A4; margin: 12mm; }
}

/* ---- tool settings panels -------------------------------------------------
   Shared by every tool's own settings panel, so a new tool gets the same look
   for free without importing anything. */

.tool__section {
    margin: 20px 0 var(--sp-2);
    font-size: var(--fs-sm);
    font-weight: 800;
    color: var(--ink-2);
}
.tool__section:first-child { margin-top: 0; }

.image-slot__preview {
    display: grid;
    place-items: center;
    height: 74px;
    margin-bottom: var(--sp-2);
    border-radius: var(--radius-sm);
    border: 1px dashed var(--line-2);
    background: var(--panel);
    color: var(--ink-3);
    font-size: var(--fs-xs);
    overflow: hidden;
}
.image-slot__preview img { max-width: 100%; max-height: 100%; object-fit: contain; }

/* ---- due card -------------------------------------------------------------
   Shared by every tool that shows something with a deadline (subscriptions,
   instalments, cheques). It lives in the platform kit so no tool has to load
   another tool's stylesheet - each tool folder stays independent.

   The stripe is never the only signal: .due-card__state says the same thing
   in words, which is what lets the yellow step stay yellow. */

.due-card {
    display: grid;
    grid-template-columns: 4px minmax(0, 1fr) auto;
    gap: var(--sp-3);
    align-items: center;
    padding: 10px var(--sp-3) 10px 0;
    border-radius: var(--radius-md);
    background: var(--surface);
    border: 1px solid var(--line);
    overflow: hidden;
}
.due-card__stripe { align-self: stretch; background: var(--line-2); border-radius: 4px 0 0 4px; }
.due-card.is-overdue .due-card__stripe { background: var(--red); }
.due-card.is-red .due-card__stripe { background: var(--red); }
.due-card.is-amber .due-card__stripe { background: var(--amber); }
.due-card.is-yellow .due-card__stripe { background: var(--yellow); }
.due-card.is-off { opacity: 0.55; }

.due-card__name { font-weight: 800; font-size: var(--fs-sm); }
.due-card__meta {
    margin-top: var(--sp-1);
    font-size: var(--fs-xs);
    color: var(--ink-3);
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-1) var(--sp-3);
}
.due-card__meta span[dir="ltr"] { direction: ltr; }
.due-card__state { font-weight: 800; }
.due-card.is-overdue .due-card__state, .due-card.is-red .due-card__state { color: var(--red-ink); }
.due-card.is-amber .due-card__state { color: var(--amber-ink); }
.due-card__actions { display: flex; gap: 5px; padding-inline-end: var(--sp-3); }
