/* The shared design system of the owner and admin portals. Colours come from branding/brand.json
   as --color-* variables (written into each page head); this file adds the rest of the tokens
   and the shared chrome. Loaded after MudBlazor's stylesheet so these rules win ties. The look
   follows tapmat.com.au: a gradient band across the header, rounded raised blocks, pill buttons
   and Lexend headings. */

/* Lexend, SIL Open Font License 1.1 (fonts/OFL.txt), the same file the website ships. */
@font-face {
    font-family: "Lexend";
    font-style: normal;
    font-weight: 500 700;
    font-display: swap;
    src: url("fonts/lexend-latin-v26.woff2") format("woff2");
}

:root {
    --space-1: 4px;
    --space-2: 8px;
    --space-3: 12px;
    --space-4: 16px;
    --space-5: 24px;
    --space-6: 32px;
    --space-7: 48px;
    --radius-sm: 8px;
    --radius-md: 20px;
    --radius-lg: 28px;
    --radius-pill: 999px;
    --font-display: "Lexend", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
    --font-sans: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    --font-mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
    --text-xs: 0.8125rem;
    --text-sm: 0.875rem;
    --text-md: 1rem;
    --text-lg: 1.25rem;
    --text-xl: 1.625rem;
    --focus-ring: 2px solid var(--color-primary-text);
    --header-height: 72px;
    --nav-width: 232px;
    --content-width: 1040px;
    --content-width-wide: 1280px;
    --target-min: 24px;
    /* The website's band behind the header and its soft block shadow. */
    --band: linear-gradient(110deg, var(--color-band-1), var(--color-band-2) 58%, var(--color-band-3));
    --shadow-block: 0 1px 2px rgb(9 40 62 / 0.05), 0 20px 40px -24px rgb(9 40 62 / 0.28);
}

:root[data-theme="dark"] {
    --shadow-block: 0 20px 40px -24px rgb(0 0 0 / 0.7);
}

@media (min-width: 1024px) {
    :root {
        --header-height: 84px;
    }
}

html, body {
    margin: 0;
    background: var(--color-background);
    color: var(--color-text-primary);
    font-family: var(--font-sans);
}

/* ---- Focus: always visible for keyboard users (WCAG 2.4.7, 2.4.11) ---------------------- */

a:focus-visible,
button:focus-visible,
summary:focus-visible,
[role="button"]:focus-visible,
[tabindex]:not([tabindex="-1"]):focus-visible,
.mud-button-root:focus-visible,
.mud-button-root:has(input:focus-visible),
.mud-expand-panel-header:focus-visible,
.mud-tab:focus-visible {
    outline: var(--focus-ring);
    outline-offset: 2px;
}

/* Headings and main receive focus only from code (FocusOnNavigate, the skip link). */
h1:focus, main:focus {
    outline: none;
}

.tl-sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* ---- Shell: banner, navigation, main ----------------------------------------------------- */

.tl-skip-link {
    position: absolute;
    left: var(--space-2);
    top: -100px;
    z-index: 1400;
    padding: var(--space-2) var(--space-4);
    border-radius: var(--radius-md);
    background: var(--color-primary);
    color: var(--color-on-primary);
    font-weight: 600;
    text-decoration: none;
}

.tl-skip-link:focus {
    top: var(--space-2);
}

.tl-shell {
    display: grid;
    grid-template-columns: var(--nav-width) minmax(0, 1fr);
    grid-template-rows: var(--header-height) 1fr;
    grid-template-areas: "header header" "nav main";
    min-height: 100vh;
}

.tl-header {
    grid-area: header;
    position: sticky;
    top: 0;
    z-index: 1100;
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: 0 var(--space-4);
    /* --look-header: a shop's colour or season (ShopLookState), over the plain background. */
    background: var(--look-header, var(--band));
    border-bottom: 1px solid var(--color-border);
}

/* Text on the band, on a page heading and on a tinted block takes the tint's own ink (checked by
   BrandContrastTests), and MudBlazor's text follows, so links and buttons stay readable. */
.tl-header,
.tl-page-header,
.tl-content .tl-section:not(.tl-section--plain):not(.tl-section--danger):not(.tl-section .tl-section) {
    --color-text-primary: var(--color-on-tint);
    --color-text-secondary: var(--color-on-tint-muted);
    --color-text-muted: var(--color-on-tint-muted);
    --color-primary-text: var(--color-on-tint);
    --mud-palette-text-primary: var(--color-on-tint);
    --mud-palette-text-secondary: var(--color-on-tint-muted);
    --mud-palette-secondary: var(--color-on-tint);
    --mud-palette-action-default: var(--color-on-tint);
    color: var(--color-on-tint);
}

.tl-brand {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    min-height: 40px;
    color: var(--color-text-primary);
    text-decoration: none;
    font-weight: 600;
    font-size: var(--text-md);
}

/* The logo is the original artwork on its own white plate in both themes, at the website's size;
   it is never recoloured for dark mode (branding/README.md). */
.tl-brand-logo {
    display: block;
    height: 44px;
    width: auto;
    padding: 4px 10px;
    border-radius: 12px;
    background: var(--color-logo-plate);
    box-shadow: 0 6px 16px -10px rgb(9 40 62 / 0.6);
}

@media (min-width: 1024px) {
    .tl-brand-logo {
        height: 52px;
    }
}

@media (max-width: 599.98px) {
    .tl-brand-logo {
        height: 38px;
        padding: 3px 8px;
    }
}

.tl-shop-logo {
    max-height: 32px;
    max-width: 120px;
    object-fit: contain;
}

.tl-brand-product {
    padding: 2px var(--space-2);
    border: 1px solid var(--color-info);
    border-radius: var(--radius-sm);
    background: var(--color-info-soft);
    color: var(--color-info);
    font-size: var(--text-xs);
    font-weight: 600;
}

/* The admin app (or any second app) wears a coloured strip so it reads as a different place. */
.tl-shell--product .tl-header {
    box-shadow: inset 0 3px 0 var(--color-info);
}

.tl-header-actions {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: var(--space-2);
    min-width: 0;
}

.tl-header-user {
    color: var(--color-text-secondary);
    font-size: var(--text-sm);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.tl-menu-button {
    display: none;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    margin-left: calc(-1 * var(--space-2));
    border: 0;
    border-radius: var(--radius-md);
    background: transparent;
    color: var(--color-text-primary);
    cursor: pointer;
}

.tl-menu-button:hover {
    background: var(--color-surface-secondary);
}

/* The theme switch: the icon of the scheme in use, which turns into the other on a switch. */
.tl-theme-switch {
    position: relative;
    display: inline-flex;
    flex: none;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    padding: 0;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: transparent;
    color: var(--color-text-secondary);
    cursor: pointer;
    overflow: hidden;
}

.tl-theme-switch:hover {
    background: var(--color-surface-secondary);
    color: var(--color-text-primary);
}

.tl-theme-switch__icon {
    position: absolute;
    transition: opacity 160ms ease-out, transform 320ms cubic-bezier(0.16, 1, 0.3, 1);
}

.tl-theme-switch[aria-checked="true"] .tl-theme-switch__sun,
.tl-theme-switch[aria-checked="false"] .tl-theme-switch__moon {
    opacity: 0;
    transform: rotate(-90deg) scale(0.5);
}

@media (prefers-reduced-motion: reduce) {
    .tl-theme-switch__icon {
        transition: none;
    }
}

.tl-nav {
    grid-area: nav;
    position: sticky;
    top: var(--header-height);
    align-self: start;
    height: calc(100vh - var(--header-height));
    overflow-y: auto;
    padding: var(--space-4) var(--space-3);
    border-right: 1px solid var(--color-border);
    box-sizing: border-box;
}

.tl-nav-group + .tl-nav-group {
    margin-top: var(--space-5);
}

.tl-nav-group-label {
    margin: 0 0 var(--space-1);
    padding: 0 var(--space-3);
    color: var(--color-text-muted);
    font-size: var(--text-xs);
    font-weight: 600;
}

.tl-nav-item {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    min-height: 40px;
    padding: 0 var(--space-3);
    border-radius: var(--radius-md);
    color: var(--color-text-secondary);
    font-size: var(--text-sm);
    font-weight: 500;
    text-decoration: none;
}

.tl-nav-item:hover {
    background: var(--color-surface-secondary);
    color: var(--color-text-primary);
}

/* Current page: weight and a bar, not colour alone (WCAG 1.4.1). */
.tl-nav-item.is-current {
    background: var(--color-primary-soft);
    color: var(--color-text-primary);
    font-weight: 600;
    box-shadow: inset 3px 0 0 var(--color-primary);
}

.tl-main {
    grid-area: main;
    min-width: 0;
}

.tl-content {
    max-width: var(--content-width);
    margin: 0 auto;
    padding: var(--space-5) var(--space-5) var(--space-7);
}

.tl-shell--wide .tl-content {
    max-width: var(--content-width-wide);
}

/* Signed out: no menu, so the content takes the whole width. */
.tl-shell:not(:has(.tl-nav)) {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: "header" "main";
}

@media (max-width: 959.98px) {
    .tl-shell {
        grid-template-columns: minmax(0, 1fr);
        grid-template-areas: "header" "main";
    }

    .tl-menu-button {
        display: inline-flex;
    }

    .tl-nav {
        display: none;
        position: fixed;
        top: var(--header-height);
        left: 0;
        right: 0;
        z-index: 1090;
        width: auto;
        height: auto;
        max-height: calc(100vh - var(--header-height));
        border-right: 0;
        border-bottom: 1px solid var(--color-border);
        background: var(--color-background);
    }

    .tl-nav.is-open {
        display: block;
    }

    .tl-content {
        padding: var(--space-4) var(--space-4) var(--space-6);
    }

    .tl-section {
        padding: var(--space-4);
    }
}

/* ---- Page structure ---------------------------------------------------------------------- */

.tl-page-header {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    justify-content: space-between;
    gap: var(--space-3) var(--space-4);
    margin-bottom: var(--space-5);
    padding: var(--space-5) var(--space-6);
    border-radius: var(--radius-lg);
    background:
        radial-gradient(60% 120% at 100% 0%, var(--color-tint-4), transparent 70%),
        linear-gradient(120deg, var(--color-tint-1), var(--color-tint-1) 40%, var(--color-tint-4));
    box-shadow: var(--shadow-block);
}

@media (max-width: 599.98px) {
    .tl-page-header {
        padding: var(--space-4);
        border-radius: var(--radius-md);
    }
}

.tl-page-heading {
    min-width: 0;
    flex: 1 1 320px;
}

.tl-page-title {
    margin: 0;
    font-family: var(--font-display);
    font-size: clamp(1.5rem, 1.2rem + 1.2vw, 2rem);
    font-weight: 600;
    line-height: 1.25;
    letter-spacing: -0.01em;
}

.tl-page-description {
    margin: var(--space-2) 0 0;
    max-width: 68ch;
    color: var(--color-text-secondary);
    font-size: var(--text-sm);
}

.tl-page-actions,
.tl-section-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2);
}

.tl-section {
    margin-bottom: var(--space-5);
    padding: var(--space-4) var(--space-5) var(--space-5);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-surface);
    box-shadow: var(--shadow-block);
}

.tl-section--plain {
    padding: 0;
    border: 0;
    background: transparent;
    box-shadow: none;
}

.tl-section--danger {
    border-color: var(--color-error);
}

.tl-section .tl-section {
    margin-bottom: var(--space-4);
    padding: 0;
    border: 0;
    background: transparent;
    box-shadow: none;
}

.tl-section-header {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--space-2) var(--space-4);
    margin-bottom: var(--space-4);
}

.tl-section-heading {
    min-width: 0;
    flex: 1 1 280px;
}

.tl-section-title {
    margin: 0;
    font-family: var(--font-display);
    font-size: var(--text-md);
    font-weight: 600;
    line-height: 1.4;
}

.tl-section-description {
    margin: var(--space-1) 0 0;
    max-width: 72ch;
    color: var(--color-text-secondary);
    font-size: var(--text-sm);
}

.tl-help {
    margin: var(--space-2) 0 0;
    max-width: 72ch;
    color: var(--color-text-muted);
    font-size: var(--text-xs);
}

/* A form laid out as fields then actions, each field full width on a phone. */
.tl-form {
    display: grid;
    gap: var(--space-3);
    max-width: 560px;
}

.tl-form--wide {
    max-width: none;
}

/* A titled group of related fields, announced with its title by screen readers. */
.tl-fieldset {
    margin: 0 0 var(--space-4);
    padding: 0;
    border: 0;
    min-width: 0;
}

.tl-fieldset > legend {
    margin-bottom: var(--space-2);
    padding: 0;
    color: var(--color-primary-text);
    font-size: var(--text-sm);
    font-weight: 600;
}

/* An edit form that replaces a list row takes the whole row. */
.tl-list-item > .tl-form {
    flex: 1 1 100%;
}

/* A short choice such as a count, side by side with others. MudSelect puts Class on an inner
   element inside its own wrapper, so the wrapper takes the size too; otherwise the select is
   narrow to look at but still a full-width box to click on and lay out. */
.tl-field-compact,
.mud-select:has(> .tl-field-compact) {
    flex: 0 1 160px !important;
}

/* A visible label for a group of controls (chips, a star rating). */
.tl-field-label {
    margin: 0 0 var(--space-2);
    color: var(--color-text-secondary);
    font-size: var(--text-sm);
    font-weight: 600;
}

/* A picker such as "Business": wide enough for a name, not the whole page. */
.tl-field-narrow,
.mud-select:has(> .tl-field-narrow) {
    max-width: 420px;
}

.tl-form-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    margin-top: var(--space-1);
}

.tl-inline-form {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: var(--space-2);
}

.tl-inline-form > .mud-input-control,
.tl-inline-form > .mud-select {
    flex: 1 1 240px;
}

.tl-inline-form > .mud-button-root {
    margin-top: 6px;
    min-height: 40px;
}

/* ---- Data display ------------------------------------------------------------------------ */

.tl-stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
    gap: var(--space-3);
    margin: 0 0 var(--space-5);
}

.tl-stat {
    padding: var(--space-4) var(--space-5);
    border-radius: var(--radius-md);
    background: var(--tile, var(--color-tint-1));
    box-shadow: var(--shadow-block);
}

/* The website's five bright tints, in turn, so neighbouring tiles never share a colour. */
.tl-stat:nth-child(5n+2) { --tile: var(--color-tint-4); }
.tl-stat:nth-child(5n+3) { --tile: var(--color-tint-2); }
.tl-stat:nth-child(5n+4) { --tile: var(--color-tint-5); }
.tl-stat:nth-child(5n+5) { --tile: var(--color-tint-3); }

.tl-stat-label {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    color: var(--color-text-secondary);
    font-size: var(--text-sm);
}

.tl-stat-value {
    margin: var(--space-2) 0 0;
    font-family: var(--font-display);
    font-size: 2rem;
    font-weight: 600;
    line-height: 1.1;
    font-variant-numeric: tabular-nums;
}

.tl-stat-hint {
    margin: var(--space-2) 0 0;
    color: var(--color-text-muted);
    font-size: var(--text-xs);
}

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

.tl-list-item {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2) var(--space-4);
    padding: var(--space-3) 0;
    border-bottom: 1px solid var(--color-border);
}

.tl-list-item:last-child {
    border-bottom: 0;
}

.tl-list-item-main {
    min-width: 0;
    flex: 1 1 240px;
}

.tl-list-item-title {
    margin: 0;
    font-weight: 600;
}

.tl-list-item-meta {
    margin: var(--space-1) 0 0;
    color: var(--color-text-secondary);
    font-size: var(--text-sm);
}

/* A switch named by its visible label: the name on the left, the switch on the right. */
.tl-switch-row .mud-switch {
    display: flex;
    justify-content: space-between;
    width: 100%;
    margin: 0;
}

.tl-switch-row .mud-switch .mud-switch-label,
.tl-switch-row .mud-switch > p {
    font-weight: 600;
}

/* Labelled horizontal bars, e.g. ratings by stars. */
.tl-bars {
    margin: 0;
}

.tl-bar-row {
    display: grid;
    grid-template-columns: 64px 1fr;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-1) 0;
}

.tl-bar-row dt {
    color: var(--color-text-secondary);
    font-size: var(--text-sm);
}

.tl-bar-row dd {
    display: grid;
    grid-template-columns: 1fr 32px;
    align-items: center;
    gap: var(--space-3);
    margin: 0;
}

.tl-bar-count {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.tl-feedback-item--low {
    box-shadow: inset 3px 0 0 var(--color-warning);
    padding-left: var(--space-3);
}

.tl-feedback-comment {
    margin: var(--space-2) 0 0;
    white-space: pre-wrap;
}

/* A long identifier or key that must wrap rather than widen the page. */
.tl-break {
    word-break: break-all;
}

/* A heading inside a section, e.g. a feature segment. */
.tl-subheading {
    margin: var(--space-5) 0 var(--space-1);
    color: var(--color-primary-text);
    font-size: var(--text-sm);
    font-weight: 600;
}

.tl-feature-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2) var(--space-4);
    padding: var(--space-3) 0;
    border-bottom: 1px solid var(--color-border);
}

.tl-mono {
    font-family: var(--font-mono);
    font-size: 0.92em;
    letter-spacing: 0.02em;
}

.tl-muted {
    color: var(--color-text-muted);
}

.tl-empty {
    padding: var(--space-5);
    border: 1px dashed var(--color-border-strong);
    border-radius: var(--radius-md);
    text-align: center;
}

.tl-empty-title {
    margin: 0;
    font-weight: 600;
}

.tl-empty-body {
    margin-top: var(--space-2);
    color: var(--color-text-secondary);
    font-size: var(--text-sm);
}

.tl-loading {
    margin: var(--space-4) 0;
}

.tl-loading-text {
    display: block;
    margin-top: var(--space-2);
    color: var(--color-text-muted);
    font-size: var(--text-sm);
}

.tl-status:empty {
    display: none;
}

.tl-status {
    margin: var(--space-3) 0;
}

/* A table row that can be chosen: the row's own button carries keyboard focus and the name. */
.tl-row-selected {
    background-color: var(--color-primary-soft) !important;
    box-shadow: inset 4px 0 0 var(--color-primary);
}

.tl-row-select {
    font-weight: 600;
}

.tl-preview {
    background: var(--color-surface-secondary);
    color: var(--color-text-secondary);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: var(--space-3);
    line-height: 1.5;
}

.tl-chip-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-1);
}

.tl-row-clickable {
    cursor: pointer;
}

.tl-nowrap {
    white-space: nowrap;
}

/* A row of actions for a list or table: a count on the left, buttons on the right. */
.tl-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2);
    margin-bottom: var(--space-3);
}

.tl-toolbar-text {
    margin: 0 auto 0 0;
    color: var(--color-text-secondary);
    font-size: var(--text-sm);
}

.tl-composer-options {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: var(--space-3) var(--space-6);
    margin-bottom: var(--space-3);
}

.tl-scroll-x {
    overflow-x: auto;
}

/* A QR code with its caption, centred under the button that made it. */
.tl-qr {
    display: flex;
    flex-direction: column;
    align-items: center;
    margin-top: var(--space-4);
    padding: var(--space-4);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    text-align: center;
}

/* Room for a reward name and its progress bar. */
.tl-progress-cell {
    min-width: 160px;
}

/* AI observations: short lines, easy to scan. */
.tl-insights {
    margin: 0;
    padding-left: var(--space-5);
}

.tl-insights li + li {
    margin-top: var(--space-2);
}

/* Help pages: steps and points that read like the printed guide. */
.tl-guide-text {
    margin: 0 0 var(--space-3);
    max-width: 72ch;
}

.tl-guide-list {
    margin: 0;
    padding-left: var(--space-5);
    max-width: 72ch;
}

.tl-guide-list li + li {
    margin-top: var(--space-2);
}

/* ---- Charts -------------------------------------------------------------------------------- */

.tl-chart {
    margin: 0 0 var(--space-4);
    padding: var(--space-4);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-surface);
}

.tl-chart-caption {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-1) var(--space-3);
    margin-bottom: var(--space-2);
}

.tl-chart-title {
    font-weight: 600;
}

.tl-chart-summary {
    color: var(--color-text-secondary);
    font-size: var(--text-sm);
}

.tl-chart-table summary {
    cursor: pointer;
    color: var(--color-primary-text);
    font-size: var(--text-sm);
    min-height: var(--target-min);
}

.tl-chart-table table {
    width: 100%;
    margin-top: var(--space-2);
    border-collapse: collapse;
    font-size: var(--text-sm);
    font-variant-numeric: tabular-nums;
}

.tl-chart-table th,
.tl-chart-table td {
    padding: var(--space-1) var(--space-2);
    border-bottom: 1px solid var(--color-border);
    text-align: left;
}

.tl-charts {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
    gap: var(--space-4);
}

/* The group buttons under a SegmentChart: they wrap on a narrow screen. */
.tl-segment-buttons {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    margin-top: var(--space-2);
}

/* ---- MudBlazor alignment ----------------------------------------------------------------- */

/* Flat, bordered surfaces in page content instead of shadows. Menus, dialogs and snackbars
   are rendered outside main and keep their elevation, since they float above the page. */
.tl-main .mud-paper:not(.mud-alert):not(.mud-expand-panel) {
    box-shadow: none;
}

.tl-main .mud-table.mud-paper,
.tl-main .mud-expansion-panels .mud-expand-panel {
    border: 1px solid var(--color-border);
    box-shadow: none;
}

/* Filled buttons too: their elevation is invisible on the dark ground but a visible shadow on
   the light one (theme switch). */
.tl-main .mud-button-filled,
.tl-main .mud-button-filled:hover,
.tl-main .mud-button-filled:active {
    box-shadow: none;
}

/* Column headings readable as headings, not as faint caps. */
.tl-main .mud-table-head .mud-table-cell {
    color: var(--color-text-secondary);
    font-size: var(--text-xs);
    font-weight: 600;
}

/* Minimum target size for small icon and text buttons (WCAG 2.5.8). */
.tl-main .mud-button-root.mud-button {
    min-height: 32px;
}

.tl-main .mud-input-numeric-spin button {
    min-width: var(--target-min);
    min-height: var(--target-min);
}

/* ---- Blazor's reconnect / error bar ------------------------------------------------------ */

#blazor-error-ui {
    background: var(--color-warning-soft);
    color: var(--color-text-primary);
    border-top: 1px solid var(--color-warning);
    bottom: 0;
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1500;
    box-sizing: border-box;
}

#blazor-error-ui .reload {
    color: var(--color-primary-text);
}

#blazor-error-ui .dismiss {
    position: absolute;
    right: 0.75rem;
    top: 0.5rem;
    cursor: pointer;
    background: transparent;
    border: 0;
    color: var(--color-text-primary);
    font-size: 1.25rem;
    min-width: var(--target-min);
    min-height: var(--target-min);
}

@media print {
    .tl-header, .tl-nav, .tl-skip-link, .no-print {
        display: none !important;
    }

    .tl-shell {
        display: block;
    }

    html, body {
        background: #ffffff;
        color: #000000;
    }
}

/* Shop branding editor (BrandingEditor.razor). */
.tl-branding-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 12px;
    margin-bottom: 12px;
}

.tl-swatch {
    width: 32px;
    height: 32px;
    border-radius: 8px;
    border: 1px solid var(--color-border-input);
    background: var(--color-primary);
}

.tl-branding-logo {
    max-height: 64px;
    max-width: 160px;
    object-fit: contain;
}

.tl-file-label {
    display: block;
    margin-bottom: 4px;
    color: var(--color-text-secondary);
}

/* Manuals on the Help pages: long-form reading, one column, printable. */
.tl-manual {
    max-width: 72ch;
}

.tl-manual h3 {
    margin: var(--space-5) 0 var(--space-2);
    font-size: var(--text-md);
}

.tl-manual p,
.tl-manual li {
    line-height: 1.6;
}

.tl-manual ol,
.tl-manual ul {
    padding-left: var(--space-5);
}

.tl-manual table {
    width: 100%;
    border-collapse: collapse;
    margin: var(--space-3) 0;
    font-size: var(--text-sm);
}

.tl-manual th,
.tl-manual td {
    padding: var(--space-2);
    border-bottom: 1px solid var(--color-border);
    text-align: left;
    vertical-align: top;
}

/* A worked example: a hairline frame, not a coloured side bar. */
.tl-manual .tl-example {
    margin: var(--space-3) 0;
    padding: var(--space-3) var(--space-4);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-surface-secondary);
}

.tl-manual .tl-plan-tag {
    margin-left: var(--space-2);
    padding: 1px 8px;
    border-radius: 999px;
    background: var(--color-primary-soft);
    color: var(--color-text-primary);
    font-size: 0.75rem;
    font-weight: 600;
    white-space: nowrap;
}

.tl-manual-contents {
    columns: 2 16rem;
    margin: 0;
    padding-left: var(--space-5);
}

@media print {
    .tl-manual .tl-example { background: none; }
}

/* "Today" homes (owner Dashboard, admin Overview): a pulse sentence, then what needs attention, as an ordered
   list of actions - not a grid of cards. Attention items carry the amber word, not just colour. */
.tl-today {
    margin: 0 0 var(--space-5);
    padding: var(--space-4) var(--space-5);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-surface);
}

.tl-today-pulse {
    margin: 0 0 var(--space-3);
    font-size: var(--text-lg);
    font-weight: 600;
    line-height: 1.3;
}

.tl-today-needs {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    margin: 0;
    padding: 0;
    list-style: none;
}

.tl-today-need {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2) var(--space-4);
    padding: var(--space-3) 0;
    border-top: 1px solid var(--color-border);
}

.tl-today-need-title {
    margin: 0;
    font-weight: 600;
}

.tl-today-need--attention .tl-today-need-title::before {
    content: "Needs you: ";
    color: var(--color-warning);
}

.tl-today-upgrade {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin: var(--space-3) 0 0;
    color: var(--color-text-secondary);
    font-size: var(--text-sm);
}

.tl-today-bar {
    height: 10px;
    margin: var(--space-2) 0 var(--space-1);
    border-radius: 999px;
    background: var(--color-surface-secondary);
    overflow: hidden;
}

.tl-today-bar > span {
    display: block;
    height: 100%;
    background: var(--color-success);
}

.tl-today-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    margin-top: var(--space-4);
}

/* A season's look (SeasonStrip.razor, SeasonLook.cs): a band, its words and decoration on a solid
   surface, and one effect under 5 seconds over the page. Text never sits on the colours. */
.tl-season {
    position: relative;
    display: flex;
    align-items: center;
    gap: var(--space-4);
    min-height: 88px;
    margin-bottom: var(--space-4);
    padding: calc(var(--space-3) + 10px) var(--space-4) var(--space-3);
    overflow: hidden;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-surface);
}

.tl-season__band {
    position: absolute;
    inset: 0 0 auto;
    height: 10px;
}

.tl-season__words {
    flex: 1;
    min-width: 0;
}

.tl-season__title {
    margin: 0;
    font-size: var(--text-lg);
    font-weight: 600;
    color: var(--color-text-primary);
}

.tl-season__detail {
    margin: var(--space-1) 0 0;
    color: var(--color-text-secondary);
}

.tl-season__decoration {
    flex: none;
    width: 72px;
    height: 72px;
    object-fit: contain;
}

.tl-season__close {
    position: absolute;
    top: calc(10px + var(--space-1));
    right: var(--space-1);
}

.tl-season__decoration.is-hidden {
    display: none;
}

.tl-season-fx {
    position: fixed;
    inset: 0;
    z-index: 1200;
    overflow: hidden;
    pointer-events: none;
}

.tl-season-fx__bit {
    position: absolute;
    opacity: 0;
    background: var(--bit-color);
    animation-timing-function: cubic-bezier(0.22, 1, 0.36, 1);
    animation-fill-mode: forwards;
}

.tl-season-fx__bit--snow {
    border-radius: 50%;
    animation-name: tl-season-fall;
    animation-timing-function: linear;
}

.tl-season-fx__bit--confetti {
    border-radius: 2px;
    animation-name: tl-season-fall-spin;
    animation-timing-function: linear;
}

.tl-season-fx__bit--petals {
    border-radius: 70% 0;
    animation-name: tl-season-fall-spin;
    animation-timing-function: ease-in-out;
}

.tl-season-fx__bit--sparkles {
    transform: rotate(45deg) scale(0);
    animation-name: tl-season-twinkle;
    animation-iteration-count: 3;
}

.tl-season-fx__bit--splash {
    border-radius: 50%;
    background: radial-gradient(circle, var(--bit-color) 0 45%, transparent 70%);
    animation-name: tl-season-bloom;
}

@keyframes tl-season-fall {
    0% { opacity: 0.95; transform: translate(0, 0); }
    85% { opacity: 0.95; }
    100% { opacity: 0; transform: translate(var(--bit-drift), 105vh); }
}

@keyframes tl-season-fall-spin {
    0% { opacity: 1; transform: translate(0, 0) rotate(0deg); }
    85% { opacity: 1; }
    100% { opacity: 0; transform: translate(var(--bit-drift), 105vh) rotate(540deg); }
}

@keyframes tl-season-twinkle {
    0%, 100% { opacity: 0; transform: rotate(45deg) scale(0); }
    50% { opacity: 1; transform: rotate(45deg) scale(1); }
}

@keyframes tl-season-bloom {
    0% { opacity: 0; transform: translate(-50%, -50%) scale(0.2); }
    40% { opacity: 0.5; }
    100% { opacity: 0; transform: translate(-50%, -50%) scale(2.4); }
}

@media (prefers-reduced-motion: reduce) {
    .tl-season-fx {
        display: none;
    }
}

/* The admin's season preview: the customer pages' colour fields behind the strip. */
.tl-season-preview {
    display: grid;
    justify-items: start;
    gap: var(--space-3);
    padding: var(--space-4);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background-color: var(--color-background);
}

.tl-season-preview .tl-season {
    width: 100%;
    margin-bottom: 0;
}

/* ---- Website look: pill buttons and chips, as on tapmat.com.au -------------------------- */

.mud-button-root.mud-button,
.mud-chip {
    border-radius: var(--radius-pill);
}

/* ---- Website look: tinted blocks and back to top --------------------------------------- */

/* Top-level sections take the website's bright tints in turn; fields, tables and panels inside
   keep the plain surface so a form still reads as white paper on a coloured block. */
.tl-content .tl-section:not(.tl-section--plain):not(.tl-section--danger):not(.tl-section .tl-section) {
    --tile: var(--color-tint-1);
    border: 0;
    background: var(--tile);
}

.tl-content .tl-section:not(.tl-section--plain):not(.tl-section--danger):not(.tl-section .tl-section):nth-of-type(5n+2) { --tile: var(--color-tint-4); }
.tl-content .tl-section:not(.tl-section--plain):not(.tl-section--danger):not(.tl-section .tl-section):nth-of-type(5n+3) { --tile: var(--color-tint-2); }
.tl-content .tl-section:not(.tl-section--plain):not(.tl-section--danger):not(.tl-section .tl-section):nth-of-type(5n+4) { --tile: var(--color-tint-5); }
.tl-content .tl-section:not(.tl-section--plain):not(.tl-section--danger):not(.tl-section .tl-section):nth-of-type(5n+5) { --tile: var(--color-tint-3); }

.tl-content .tl-section:not(.tl-section--plain):not(.tl-section--danger):not(.tl-section .tl-section) .mud-input.mud-input-outlined,
.tl-page-header .mud-input.mud-input-outlined {
    background: var(--color-surface);
    border-radius: var(--radius-sm);
}

/* Appears once the page has scrolled a screen (taploop-ui.js), for long pages on a phone. */
.tl-back-to-top {
    position: fixed;
    right: max(var(--space-4), env(safe-area-inset-right));
    bottom: max(var(--space-4), env(safe-area-inset-bottom));
    z-index: 1200;
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    min-height: 44px;
    padding: 0 var(--space-4);
    border: 0;
    border-radius: var(--radius-pill);
    background: var(--color-primary);
    color: var(--color-on-primary);
    font: 600 var(--text-sm) / 1 var(--font-sans);
    box-shadow: 0 12px 24px -12px rgb(9 40 62 / 0.7);
    cursor: pointer;
    opacity: 0;
    visibility: hidden;
    transform: translateY(12px);
    transition: opacity 200ms cubic-bezier(0.16, 1, 0.3, 1), transform 200ms cubic-bezier(0.16, 1, 0.3, 1), visibility 200ms;
}

.tl-scrolled .tl-back-to-top {
    opacity: 1;
    visibility: visible;
    transform: none;
}

.tl-back-to-top:hover {
    background: var(--color-primary-hover);
}

@media (prefers-reduced-motion: reduce) {
    .tl-back-to-top {
        transition: none;
    }
}

@media print {
    .tl-back-to-top {
        display: none;
    }
}
