/* ─────────────────────────────────────────────────────────────
   Clyffe — Design system component styles (shared by all web apps)
   Consumed via _content/Clyffe.DesignSystem/clyffe-components.css,
   linked after clyffe-tokens.css. Uses tokens only — no raw values.
   ───────────────────────────────────────────────────────────── */

/* ── Utilities ── */
.cursor-pointer {
    cursor: pointer;
}

/* ── Brand canvas (the surface you meet Clyffe on) ──
   Full-bleed navy carrying the logo's concentric arcs at a few percent white — the treatment the
   brand reserves for entry screens. Signing in and setting up are one arrival, so they are one
   definition here rather than a navy in the door's stylesheet and another in the app's, which is
   how two entry screens end up almost the same colour. Cards sitting on it stay white. */
.clyffe-brand-canvas {
    background-color: var(--navy);
    background-image:
        radial-gradient(circle at 85% 20%, transparent 0 118px, var(--white-08) 118px 119px, transparent 119px 100%),
        radial-gradient(circle at 85% 20%, transparent 0 186px, var(--white-05) 186px 187px, transparent 187px 100%),
        radial-gradient(circle at 85% 20%, transparent 0 254px, var(--white-03) 254px 255px, transparent 255px 100%);
    /* Anchored to the viewport, so a setup screen that scrolls does not drag the arcs up with it. */
    background-attachment: fixed;
    background-repeat: no-repeat;
}

/* ── Brand lockup (the mark beside the name) ──
   The one way Clyffe signs a screen: the icon and "Clyffe" set in Crimson Pro. The asset pack
   also ships a "CLYFFE.IO" capitals wordmark; that is a marketing lockup and never appears on
   the customer surface (#578). Two tones because the lockup sits on navy entry surfaces and on
   white cards, and two sizes because the sidebar's is smaller than an entry screen's — nothing
   else varies. */
.clyffe-lockup {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
}

.clyffe-lockup-mark {
    display: block;
    flex-shrink: 0;
    object-fit: contain;
}

.clyffe-lockup-name {
    font-family: var(--font-display);
    font-weight: var(--weight-display-medium);
    line-height: 1;
    letter-spacing: 0.01em;
}

.clyffe-lockup-on-navy .clyffe-lockup-name {
    color: var(--parchment);
}

.clyffe-lockup-on-light .clyffe-lockup-name {
    color: var(--text-display);
}

.clyffe-lockup-sm .clyffe-lockup-mark {
    width: 26px;
    height: 26px;
}

.clyffe-lockup-sm .clyffe-lockup-name {
    font-size: 22px;
}

.clyffe-lockup-lg .clyffe-lockup-mark {
    width: 34px;
    height: 34px;
}

.clyffe-lockup-lg .clyffe-lockup-name {
    font-size: var(--text-h1-size);
}

/* ── Product logo tile ──
   One treatment for every product in the app, whether we fetched a logo for it or fall back to
   its initial: a white tile, one radius, one size ramp off the control-height scale. Until #578
   the fallback sat on a navy MudAvatar and the fetched logo on white, so one list showed two
   kinds of thing; white is the one the vendors' own artwork is drawn for, and it keeps a column
   of logos quiet (Jamie's call, 28 Aug — the issue text had said parchment). The hairline is
   what makes it a tile rather than a floating mark on a white card. */
.clyffe-app-logo {
    background-color: var(--surface-card);
    color: var(--text-strong);
    border: var(--border-card);
    border-radius: var(--radius-sm);
    font-family: var(--font-body);
    font-weight: var(--weight-body-semibold);
    overflow: hidden;
}

.clyffe-app-logo-img {
    width: 100%;
    height: 100%;
    object-fit: contain;
}

/* A logo made for a dark background (#1116): a light mark the white tile would swallow, so a
   wrapper that knows the logo's theme puts the same tile on ink. Used wherever an organisation's
   own logo is drawn (the sidebar badge, Settings, the onboarding preview); the tile stays one
   treatment with one variant, described here and nowhere else. */
.clyffe-logo-on-ink .clyffe-app-logo {
    background-color: var(--ink);
    border-color: var(--ink);
}

/* Compounded so the ramp out-specifies MudAvatar's own per-size width/height. */
.clyffe-app-logo.clyffe-app-logo-sm {
    width: var(--control-height-sm);
    height: var(--control-height-sm);
    font-size: var(--text-caption-size);
}

.clyffe-app-logo.clyffe-app-logo-md {
    width: var(--control-height-md);
    height: var(--control-height-md);
    font-size: var(--text-body-size);
}

.clyffe-app-logo.clyffe-app-logo-lg {
    width: var(--control-height-lg);
    height: var(--control-height-lg);
    font-size: var(--text-h2-size);
}

/* ── Empty state (calm, quiet — no alarm styling) ── */
.clyffe-empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: var(--space-2);
    padding: var(--space-6) var(--space-4);
}

.clyffe-empty-state-icon {
    color: var(--navy-40);
}

.clyffe-empty-state-title {
    font-family: var(--font-display);
    font-size: var(--text-h2-size);
    font-weight: var(--weight-display-medium);
    color: var(--text-heading);
}

.clyffe-empty-state-description {
    max-width: 420px;
    font-size: var(--text-body-size);
    line-height: var(--leading-body);
    color: var(--text-body);
}

.clyffe-empty-state-actions {
    margin-top: var(--space-2);
    display: flex;
    gap: var(--space-2);
}

/* ── Page transition (subtle fade on navigation — nothing snaps) ──
   Opacity only, deliberately: animating transform makes the wrapper the containing
   block for position: fixed descendants, which clipped the detail panes to the page
   content instead of the viewport. */

.clyffe-page-transition {
    animation: clyffe-page-enter var(--duration-panel) var(--ease-out) both;
}

@keyframes clyffe-page-enter {
    from {
        opacity: 0;
    }
    to {
        opacity: 1;
    }
}

/* ── Skeleton loading (skeletons over spinners; navy-to-cream pulse) ── */

.clyffe-skeleton {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    padding: var(--space-2) 0;
}

.clyffe-skeleton-row {
    height: 40px;
    border-radius: var(--radius-xs);
    background: linear-gradient(90deg, var(--navy-05), var(--parchment-50), var(--navy-05));
    background-size: 200% 100%;
    animation: clyffe-skeleton-pulse 1.6s var(--ease-in-out) infinite;
}

@keyframes clyffe-skeleton-pulse {
    from {
        background-position: 200% 0;
    }
    to {
        background-position: -200% 0;
    }
}

@media (prefers-reduced-motion: reduce) {
    .clyffe-page-transition {
        animation: none;
    }

    .clyffe-skeleton-row {
        animation: none;
        background: var(--navy-05);
    }
}

/* ── Card (the surface everything on a page sits on) ──
   Flat by brand: white, one hairline border at 8% navy, 2px radius, never a shadow — a card is
   a surface, not a floating layer. Declared here rather than per app because the page header
   below is one, and a second definition is how the two drifted apart in the first place. */
.clyffe-card {
    border: var(--border-card);
    border-radius: var(--radius-xs);
    background: var(--white);
    box-shadow: none;
}

/* ── Page header (the one way a page introduces itself) ──
   Twenty-one pages hand-rolled this block, the home screen drew a bare heading with no card,
   and the setup screens used a third vocabulary of their own (#579). The spacing and type of a
   page title now live here and nowhere else. */
.clyffe-page-header {
    padding: var(--pad-card);
}

.clyffe-page-header-back {
    margin-bottom: var(--space-2);
}

.clyffe-page-header-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: var(--space-3);
}

/* The logo, the title block and anything sitting beside the title read as one unit, so they
   stay together when the actions wrap onto their own line. */
.clyffe-page-header-lead {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--space-3);
    min-width: 0;
}

/* The title block is a flex item beside the logo and the adornment. Without this a long title
   refuses to shrink and pushes the page's actions off the end of the row. */
.clyffe-page-header-heading {
    min-width: 0;
}

.clyffe-page-header-title {
    margin: 0;
    font-family: var(--font-display);
    font-size: var(--text-h1-size);
    font-weight: var(--weight-display);
    line-height: var(--leading-heading);
    color: var(--text-display);
}

/* Blazor's FocusOnNavigate puts focus on the h1 so a screen reader announces the new page.
   That is the announcement we want and the focus ring we do not. */
.clyffe-page-header-title:focus,
.clyffe-page-header-title:focus-visible {
    outline: none;
    box-shadow: none;
}

.clyffe-page-header-subtitle {
    margin: var(--space-1) 0 0;
    font-family: var(--font-body);
    font-size: var(--text-body-size);
    font-weight: var(--weight-body);
    line-height: var(--leading-body);
    color: var(--text-body);
    max-width: 70ch;
}

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

.clyffe-page-header-body {
    margin-top: var(--space-3);
}

/* ── Secondary navigation (the one row of switchable labels) ──
   An area's pages and a page's filters are the same control wearing two hats, so they are drawn
   from one definition (issue #581). Cove, not navy: the sidebar is the product and owns navy;
   this row is context inside whatever the sidebar selected, and the brand's secondary colour is
   what says so. The two roles differ in what they do — a link versus a control — not in how they
   look, so the reader learns the shape once; that is why the role lands on the container as a
   class and a screen-reader role, and styles nothing. Spacing is the caller's, through Class. */
.clyffe-section-nav {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2);
}

.clyffe-section-nav-item {
    display: inline-flex;
    align-items: center;
    min-height: var(--control-height-sm);
    padding: 0 var(--space-3);
    border: var(--border-width) solid var(--border-hairline);
    border-radius: var(--radius-sm);
    background: var(--surface-card);
    color: var(--text-body);
    font-family: var(--font-body);
    font-size: var(--text-caption-size);
    font-weight: var(--weight-body-semibold);
    line-height: var(--leading-ui);
    letter-spacing: var(--tracking-ui);
    /* The label stays on one line: a wrapped tab is taller than the ones beside it, which is the
       ragged row of controls the sizing rules exist to stop. */
    white-space: nowrap;
    text-decoration: none;
    cursor: pointer;
    transition: var(--transition-micro);
}

.clyffe-section-nav-item:hover {
    border-color: var(--cove);
    color: var(--ink);
}

.clyffe-section-nav-item-active {
    background: var(--cove);
    border-color: var(--cove);
    color: var(--white);
}

/* ── Searchable select (the one dropdown) ──
   Every picker over a list the business owns is this control (issue #694): the reader types
   rather than scrolls, and a name only ever carries an address where the name alone would name
   two people. The row and the chosen-token strip are styled here so no page can grow a second
   look for the same control. ── */
.clyffe-select {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

.clyffe-select-option {
    display: flex;
    flex-direction: column;
    gap: 0;
}

.clyffe-select-option-label {
    font-family: var(--font-body);
    font-size: var(--text-body-size);
    color: var(--text-strong);
    line-height: var(--leading-ui);
}

/* The disambiguating line. Quieter than the name it sits under, because it is there to tell two
   rows apart rather than to be read on its own. */
.clyffe-select-option-secondary {
    font-family: var(--font-body);
    font-size: var(--text-caption-size);
    color: var(--text-muted);
    line-height: var(--leading-ui);
}

.clyffe-select-empty {
    font-family: var(--font-body);
    font-size: var(--text-caption-size);
    color: var(--text-muted);
    padding: var(--space-2) var(--space-3);
}

/* What a multi-select has been set to. Tokens, not badges: each one is the control that takes
   itself back off, which is the opposite of what a status pill means. */
.clyffe-select-tokens {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-1);
}

.clyffe-select-token {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    min-height: var(--control-height-sm);
    padding: 0 var(--space-2);
    background: var(--surface-sunken);
    border: 1px solid var(--border-hairline);
    border-radius: var(--radius-sm);
    font-family: var(--font-body);
    font-size: var(--text-caption-size);
    color: var(--text-strong);
    cursor: pointer;
    transition: var(--transition-micro);
}

.clyffe-select-token:hover:not(:disabled) {
    border-color: var(--cove);
}

.clyffe-select-token:disabled {
    cursor: default;
    color: var(--text-muted);
}

.clyffe-select-token-remove {
    font-size: var(--text-body-size);
    line-height: 1;
    color: var(--text-muted);
}
