﻿/* Cards */
.syc-card {
    background: var(--syc-surface);
    border: 1px solid var(--syc-border);
    border-radius: var(--syc-radius-lg);
    box-shadow: var(--syc-shadow);
    overflow: hidden;
    transition: box-shadow var(--syc-transition), transform var(--syc-transition);
}

/* Cards holding a long form with a sticky action bar. position: sticky is disabled by any
   clipping ancestor, and .syc-card clips to its rounded corners — so this variant opts out.
   Safe on forms, which have no full-bleed children needing the clip. */
.syc-card-form {
    overflow: visible;
}

.syc-card:hover {
    box-shadow: var(--syc-shadow-lg);
}

.syc-card-header {
    background: var(--syc-surface-alt);
    border-bottom: 1px solid var(--syc-border);
    padding: 0.875rem 1.25rem;
    font-weight: 600;
    font-size: 0.875rem;
    color: var(--syc-text);
    letter-spacing: 0.02em;
    text-transform: uppercase;
}

.syc-card-body { padding: 1.25rem; }

/* Photo Cards for closet items */
.syc-item-card {
    /* A positioning context, so anything placed absolutely inside lands on this card. Without it
       the selection tick anchored to the page instead, and every tick in the grid stacked in the
       same corner -- which looked exactly like one checkmark jumping from item to item. */
    position: relative;
    background: var(--syc-surface);
    border: 1px solid var(--syc-border);
    border-radius: var(--syc-radius-lg);
    overflow: hidden;
    transition: box-shadow var(--syc-transition), transform var(--syc-transition);
    display: flex;
    flex-direction: column;
}

.syc-item-card:hover {
    box-shadow: var(--syc-shadow-lg);
    transform: translateY(-2px);
}

/* Clickable card (e.g. Browse — click to open details/borrow). */
.syc-item-card-clickable { cursor: pointer; }
.syc-item-card-clickable:hover { border-color: var(--syc-accent); }

.syc-item-card-photo {
    position: relative;               /* image is absolutely positioned inside */
    width: 100%;
    aspect-ratio: 1 / 1;              /* square — consistent with the detail/edit gallery */
    overflow: hidden;                 /* clip whatever shape the photo is */
    background-color: var(--syc-surface-alt);
    display: grid;
    place-items: center;              /* centers the placeholder icon */
    color: var(--syc-text-light);
    font-size: 2rem;
}

/* Absolutely positioned so a tall/rectangular image can never push into the body below; the fixed
   aspect-ratio box always defines the height.

   contain, not cover — the same reasoning as .syc-item-image further down, which was fixed while
   this was missed. cover fills the square by clipping whatever doesn't fit, so a deliberately
   cropped portrait photo came back to the browse grid trimmed top and bottom: the app quietly
   overruling a crop the user had just made by hand. Letterboxing against the surface colour keeps
   every card the same size while showing the whole garment.

   The small thumbnails elsewhere (.syc-thumbnail-img, .syc-extra-photo, .syc-bulk-thumb) keep
   cover on purpose — at 64-72px nobody is judging a garment by its edges. */
.syc-item-card-photo img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: contain;
    object-position: center;
    display: block;
}

/* Card image carousel arrows */
/* Scoped to the card. The item-detail gallery further down uses the same .syc-carousel-arrow
   class, and an unscoped block here silently overrode half its styling (and vice versa) — same
   specificity, so whichever came last in the file won. */
.syc-item-card-photo .syc-carousel-arrow {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    z-index: 1;
    width: 30px;
    height: 30px;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: none;
    border-radius: 50%;
    /* Dark with a white glyph, not the reverse. Since the card photo switched to object-fit:
       contain, a portrait photo letterboxes against the light surface colour — and the arrows sit
       right on top of that strip, where a white circle was effectively invisible. Dark reads
       against the letterbox, a pale garment, and a dark one alike. */
    background: rgba(0, 0, 0, 0.55);
    color: #fff;
    font-size: 0.9rem;
    cursor: pointer;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.35);
    opacity: 1;
    transition: opacity var(--syc-transition), background var(--syc-transition);
}
.syc-item-card-photo .syc-carousel-arrow:hover { background: rgba(0, 0, 0, 0.78); }
.syc-carousel-prev { left: 6px; }
.syc-carousel-next { right: 6px; }
/* Pointer devices: keep cards clean, reveal arrows on hover. Touch (no hover) keeps them always
   visible via the base rule above. Scoped to the card — unscoped, this hid the item-detail
   gallery's arrows too, and nothing there ever revealed them again. */
@media (hover: hover) {
    .syc-item-card-photo .syc-carousel-arrow { opacity: 0; }
    .syc-item-card-photo:hover .syc-carousel-arrow { opacity: 1; }
}

.syc-item-card-body {
    padding: 0.875rem 1rem;
    flex: 1;
}

.syc-item-card-name {
    font-weight: 600;
    font-size: 0.9rem;
    color: var(--syc-text);
    margin-bottom: 0.25rem;
    /* Its own line, under the name rather than tucked against it. Reported as having no space
       between the two, and the screenshot showed worse than that -- the date sitting on top of the
       trip's name, greyed and half hidden behind it. The column and gap above fix the overlap;
       this keeps the line its own height rather than borrowing the heading's. */
    line-height: 1.3;
    text-align: center;
}

.syc-item-card-meta {
    font-size: 0.8rem;
    color: var(--syc-text-muted);
    margin-bottom: 0.125rem;
}

.syc-item-card-desc {
    font-size: 0.8rem;
    color: var(--syc-text);
    margin: 0.25rem 0;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.syc-item-card-season {
    display: inline-block;
    font-size: 0.72rem;
    color: var(--syc-accent-dark);
    background: var(--syc-accent-subtle);
    border-radius: 20px;
    padding: 0.15rem 0.6rem;
    margin-top: 0.25rem;
    font-weight: 500;
}

.syc-item-card-actions {
    display: flex;
    border-top: 1px solid var(--syc-border);
    background: var(--syc-surface-alt);
}

.syc-item-card-actions .btn {
    flex: 1;
    border: none;
    border-radius: 0;
    font-size: 0.75rem;
    padding: 0.5rem 0.25rem;
    color: var(--syc-text-muted);
    background: transparent;
    border-right: 1px solid var(--syc-border);
    transition: all var(--syc-transition);
}

.syc-item-card-actions .btn:last-child {
    border-right: none;
}

.syc-item-card-actions .btn:hover {
    background: var(--syc-surface);
    color: var(--syc-primary);
}

.syc-item-card-actions .btn.danger:hover {
    background: #FFF0EF;
    color: var(--syc-danger);
}

/* Contact footer on a shared-item card */
.syc-item-card-share {
    border-top: 1px solid var(--syc-border);
    background: var(--syc-surface-alt);
    padding: 0.45rem 0.6rem;
    font-size: 0.72rem;
    text-align: center;
    word-break: break-all;
}

/* Card grid — wider tiles so the name, details and description have room */
.syc-card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
    gap: 0.85rem;
}

@media (max-width: 576px) {
    /* Two across on a phone.

       It was three, on the reasoning that a garment stripped of its name and details needs only its
       own width, so more of the wardrobe fits on a screen. More of it did fit, and it was harder to
       use: the grid is where people judge their own clothes -- "is that the charcoal one or the
       green one" -- and at a third of a phone screen a photograph does not answer that. Two across
       is the size at which the tile is worth looking at, which is the whole job of this screen. */
    .syc-card-grid {
        grid-template-columns: repeat(2, 1fr);
        gap: 0.6rem;
    }
}

/* My Closet section header (title + secondary actions; replaces the old ribbon) */
.syc-closet-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-bottom: 1rem;
}
.syc-closet-title {
    font-size: 1.4rem;
    font-weight: 600;
    margin: 0;
    color: var(--syc-text);
}
.syc-closet-actions {
    display: flex;
    gap: 0.4rem;
    flex-wrap: wrap;
}

/* Floating action button for "add item" (#125). Fixed rather than in the header, so it stays under
   the thumb however far the closet is scrolled, and costs no layout width -- which matters on the
   375pt screens two testers use. A round + is the established convention; title and aria-label
   carry the words for anyone the icon alone doesn't reach.
   The list gets matching bottom padding (.syc-closet-content) so the last row is never hidden. */
.syc-fab {
    position: fixed;
    right: 1rem;
    bottom: calc(1rem + env(safe-area-inset-bottom, 0px));
    z-index: 1030;
    width: 60px;
    height: 60px;
    border-radius: 50%;
    background: var(--syc-primary);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.28);
    text-decoration: none;
    /* It's a <button> now that it opens the add sheet rather than navigating, so the browser's
       default button border and padding have to go or the circle stops being a circle. */
    border: none;
    padding: 0;
    cursor: pointer;
    transition: transform var(--syc-transition), box-shadow var(--syc-transition);
}

.syc-fab .bi {
    font-size: 1.75rem;
    line-height: 1;
}

.syc-fab:hover,
.syc-fab:focus {
    color: #fff;
    transform: translateY(-2px);
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.34);
}

.syc-fab:focus-visible {
    outline: 3px solid var(--syc-accent);
    outline-offset: 3px;
}

/* Room for the button to sit over without covering the last item. */
.syc-fab-spacer {
    height: 92px;
}

/* The inline header button, for screens wide enough that a viewport-corner FAB would float
   somewhere unrelated to the content. Hidden on phones, where the FAB is the better answer. */
.syc-add-item-inline {
    display: none;
    font-size: 1rem;
    font-weight: 600;
    padding: 0.5rem 1.1rem;
    border-radius: 999px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
    align-items: center;
    gap: 0.45rem;
}

.syc-add-item-inline .bi { font-size: 1.15rem; }
.syc-add-item-inline:hover { box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2); }

/* 992px is Bootstrap's lg — the point where the closet stops being a single full-width column. */
@media (min-width: 992px) {
    .syc-add-item-inline { display: inline-flex; }
    .syc-fab,
    .syc-fab-spacer { display: none; }
}

/* Profile page links */
.syc-profile-links {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    max-width: 480px;
}
.syc-profile-link {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.85rem 1rem;
    border: 1px solid var(--syc-border);
    border-radius: var(--syc-radius);
    background: var(--syc-surface);
    color: var(--syc-text);
    text-decoration: none;
    transition: border-color var(--syc-transition), background var(--syc-transition);
}
.syc-profile-link:hover:not(.disabled) {
    border-color: var(--syc-accent);
    background: var(--syc-accent-subtle);
}
.syc-profile-link.disabled { opacity: 0.6; cursor: default; }

/* My Closet filter pills */
.filter-pills {
    display: flex;
    gap: 0.5rem;
    margin-bottom: 1.25rem;
    flex-wrap: wrap;
}
.pill {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    padding: 0.375rem 0.875rem;
    border-radius: 999px;
    border: 1.5px solid var(--syc-border);
    background: transparent;
    color: var(--syc-text);
    font-size: 0.875rem;
    cursor: pointer;
    transition: all 0.15s;
}
.pill:hover { border-color: var(--syc-accent); }
.pill.active {
    background: var(--syc-primary);
    border-color: var(--syc-primary);
    color: #fff;
    font-weight: 600;
}
.pill-count { font-size: 0.75rem; opacity: 0.8; }

/* Card status badges (shown on the "All" view) */
.syc-card-badges { display: flex; flex-wrap: wrap; gap: 0.3rem; margin-top: 0.35rem; }
.status-badge {
    display: inline-flex;
    align-items: center;
    font-size: 0.7rem;
    padding: 0.15rem 0.5rem;
    border-radius: 999px;
    font-weight: 500;
}
.status-badge.shared {
    background: color-mix(in srgb, var(--syc-info) 15%, transparent);
    color: var(--syc-info);
}
.status-badge.donating {
    background: var(--syc-accent-subtle);
    color: var(--syc-accent-dark);
}
.status-badge.pending {
    background: color-mix(in srgb, var(--syc-primary) 15%, transparent);
    color: var(--syc-primary);
}

/* Clothing-type dropdown (accordion) groups */
.syc-type-group {
    border: 1px solid var(--syc-border);
    border-radius: var(--syc-radius);
    background: var(--syc-surface);
    margin-bottom: 0.75rem;

    /* clip, not hidden, and the difference is a feature that would otherwise have shipped dead.
       overflow:hidden makes a scroll container, and a sticky descendant sticks to its nearest
       scrolling ancestor -- so the heading below would have stuck to a box that never scrolls and
       done nothing at all. clip still rounds the corners off the grid inside. */
    overflow: clip;
}
.syc-type-summary {
    list-style: none;
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 0.5rem;   /* count sits right next to the type name, not way off to the right */
    padding: 0.6rem 0.9rem;
    font-weight: 700;
    font-size: 0.95rem;
    color: var(--syc-text);
    background: var(--syc-surface-alt);
}
/* The heading stays while you are inside its type.

   Reported from a real closet: a hundred and thirty-six shirts, scrolled well down, and then
   wanting the bottoms -- which meant scrolling all the way back up to shut Tops and open Bottoms.
   The heading is both the label and the control, so pinning it means you can always see which type
   you are in and always close it from where you are.

   Only inside the picker's own scroller. On the closet screen the whole window scrolls and the
   controls row is already sticky at the top of it, so a heading pinned at nought would sit behind
   that row -- a second, harder problem, deliberately not solved here.

   Sticks at the top of the scrollport, which is directly under the controls: they are outside
   .syc-picker-body, so nothing of the sheet's chrome is in the way. */
.syc-picker-body .syc-type-summary {
    position: sticky;
    top: 0;

    /* Above the grid it is pinned over, which paints garment cards. */
    z-index: 2;
}

/* Where a category lands when it is opened -- see picker.js.
   Flush under the controls, which is where its heading is about to pin itself anyway. */
.syc-picker-body .syc-type-group { scroll-margin-block-start: 0; }

.syc-type-summary::-webkit-details-marker { display: none; }
.syc-type-summary::before {
    content: "\25B8";
    display: inline-block;
    margin-right: 0.5rem;
    color: var(--syc-text-muted);
    transition: transform 0.15s ease;
}
.syc-type-group[open] > .syc-type-summary::before { transform: rotate(90deg); }
.syc-type-count {
    font-weight: 500;
    color: var(--syc-text-muted);
    background: var(--syc-surface);
    border: 1px solid var(--syc-border);
    border-radius: 20px;
    padding: 0.05rem 0.5rem;
    font-size: 0.75rem;
}
.syc-type-group .syc-card-grid { padding: 0.85rem; }

/* Season section */
.syc-season-section {
    margin-bottom: 2.5rem;
}

.syc-season-label {
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--syc-text-muted);
    margin-bottom: 1rem;
    padding-bottom: 0.5rem;
    border-bottom: 1px solid var(--syc-border);
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.syc-season-count {
    font-weight: 400;
    color: var(--syc-text-light);
}

/* Old row styles kept for donation/share pages */
.syc-season-group { margin-bottom: 1.5rem; }
.syc-season-header {
    background-color: var(--syc-primary);
    color: white;
    padding: 0.6rem 1rem;
    border-radius: var(--syc-radius) var(--syc-radius) 0 0;
    font-weight: 500;
    font-size: 0.85rem;
    letter-spacing: 0.05em;
    text-transform: uppercase;
}
.syc-season-items {
    border: 1px solid var(--syc-border);
    border-top: none;
    border-radius: 0 0 var(--syc-radius) var(--syc-radius);
    background: var(--syc-surface);
}
.syc-item-row {
    padding: 0.75rem 1rem;
    border-bottom: 1px solid var(--syc-border);
}
.syc-item-row:last-child { border-bottom: none; }
.syc-item-data {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr auto;
    gap: 0.5rem;
    align-items: center;
    font-size: 0.875rem;
}
.syc-item-actions {
    display: flex;
    gap: 0.4rem;
    margin-top: 0.4rem;
    flex-wrap: wrap;
}
.syc-item-actions .btn { font-size: 0.78rem; padding: 0.2rem 0.6rem; }
.syc-detail-panel {
    background: var(--syc-accent-subtle);
    border-radius: var(--syc-radius);
    padding: 0.75rem 1rem;
    margin-top: 0.5rem;
    font-size: 0.875rem;
    border-left: 3px solid var(--syc-accent);
}

/* Closet two-column grid */
.syc-closet-seasons-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1.5rem;
}
@media (max-width: 768px) {
    .syc-closet-seasons-grid { grid-template-columns: 1fr; }
}

/* Analyze tables */
.syc-analyze-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 1.25rem;
}
@media (max-width: 900px) {
    .syc-analyze-grid { grid-template-columns: 1fr; }
}
.syc-analyze-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.875rem;
}
.syc-analyze-table th {
    background-color: var(--syc-primary);
    color: white;
    padding: 0.6rem 0.75rem;
    text-align: left;
    font-weight: 500;
    font-size: 0.8rem;
    letter-spacing: 0.04em;
}
.syc-analyze-table td {
    padding: 0.5rem 0.75rem;
    border-bottom: 1px solid var(--syc-border);
}
.syc-analyze-table tr:last-child td { border-bottom: none; }
.syc-analyze-table tr:nth-child(even) td { background-color: var(--syc-surface-alt); }

/* Badges */
.syc-badge-category {
    background-color: var(--syc-surface-alt);
    color: var(--syc-primary);
    border: 1px solid var(--syc-border);
    border-radius: 20px;
    padding: 0.15rem 0.6rem;
    font-size: 0.75rem;
    font-weight: 500;
}

.syc-badge-season {
    background-color: var(--syc-accent-subtle);
    color: var(--syc-accent-dark);
    border: 1px solid var(--syc-accent-light);
    border-radius: 20px;
    padding: 0.15rem 0.6rem;
    font-size: 0.75rem;
    font-weight: 500;
}

/* Forms */
.syc-form-label {
    font-weight: 500;
    font-size: 0.85rem;
    color: var(--syc-text);
    margin-bottom: 0.35rem;
}

/* Alerts */
.syc-alert-success {
    background-color: #EFF7F1;
    border-color: #B8DEC1;
    color: #2D6B3F;
    border-radius: var(--syc-radius);
    padding: 0.75rem 1rem;
}
.syc-alert-danger {
    background-color: #FDF0EF;
    border-color: #F0C4C2;
    color: #8B3330;
    border-radius: var(--syc-radius);
    padding: 0.75rem 1rem;
}
/* Build stamp on the sign-in screen — deliberately faint. It exists so a tester can read it out,
   not to be part of the design. */
.syc-build-stamp {
    text-align: center;
    font-size: 0.7rem;
    color: var(--syc-text-muted);
    opacity: 0.7;
    margin: 1.25rem 0 0;
}
/* Beta-only aside: quieter than an alert, since it's context rather than something to act on.
   Remove alongside the BetaEmailDelayNotice constants when testing ends. */
.syc-beta-note {
    font-size: 0.8rem;
    line-height: 1.5;
    color: var(--syc-text-muted);
    text-align: center;
}
/* Guidance rather than a problem — the first-run "set up your closet profile" prompt. */
.syc-alert-info {
    background-color: #E6EFF0;
    border-color: #B9D0D3;
    color: var(--syc-primary-dark);
    border-radius: var(--syc-radius);
    padding: 0.75rem 1rem;
}

/* Empty state */
.syc-empty-state {
    padding: 4rem 2rem;
    text-align: center;
    color: var(--syc-text-muted);
}
.syc-empty-icon {
    font-size: 3rem;
    color: var(--syc-border);
    display: block;
    margin-bottom: 1rem;
}

/* Loading */
.syc-spinner { color: var(--syc-accent); }

/* ── Waiting ──────────────────────────────────────────────────────────────────
   The hanger, turning. See BrandSpinner for why it is not Bootstrap's arc any more.

   The mark is drawn in currentColor and the rail in the accent, exactly as BrandMark is, so it
   takes its weight from whatever it is sitting in rather than declaring a colour of its own. */
.syc-brand-spinner {
    display: inline-grid;
    place-items: center;

    /* Slate, with the rail left in blush -- the two-colour mark, the way it reads in the header.
       It was accent-dark over accent, which is two shades of the same blush: on a pale ground the
       rail disappeared into the hanger and the mark was one flat colour. The header's version is
       white over blush and reads at a glance, and this is that relationship right way up for a
       light screen. */
    color: var(--syc-primary, #1F4A54);
}

.syc-brand-spinner-mark {
    width: 2.25rem;
    height: auto;

    /* Swinging from the hook, which is the only thing a hanger on a rail does.

       It turned a full circle first, and about its centre before that. Centred it tumbled end over
       end -- technically a rotation and not a thing a hanger has ever done -- and moving the origin
       to the hook fixed the axis but not the motion: a hanger going all the way round is still a
       hanger doing something hangers do not.

       The hook is at (38, 4) in a 60x48 box, which is 63% across and 8% down. */
    transform-origin: 63% 8%;

    /* Eased at both ends and symmetrical about nought, so it slows into each turn the way weight
       on a hook does. Linear would be a windscreen wiper. */
    animation: syc-hanger-swing 1.6s ease-in-out infinite;
}

@keyframes syc-hanger-swing {
    /* Started and finished at rest rather than at an extreme, so the first thing anybody sees is a
       hanger hanging -- and a wait short enough to catch only one frame of this looks like the
       mark rather than like something caught mid-fall. */
    0%, 100% { transform: rotate(0deg); }
    25% { transform: rotate(-15deg); }
    75% { transform: rotate(15deg); }
}

/* Still, for anybody who has asked for less movement. The mark stays, because a blank space with
   nothing in it is not a shorter wait -- it is a wait with nothing to look at. */
@media (prefers-reduced-motion: reduce) {
    .syc-brand-spinner-mark { animation: none; }
}

/* The big one: a screen with nothing else on it. */
.syc-brand-spinner-lg .syc-brand-spinner-mark { width: 4rem; }

/* A page waiting for its own contents, in the middle of the window.

   Twice wrong before this. A centred div with padding centres across and not down, so the mark sat
   wherever the content above it happened to end -- and then a tall box sized off the header and
   the tab bar, which only moved the problem: the box begins after whatever the page has already
   drawn, so it still landed high on one screen and low on another. Reported both times, the second
   as "in some screens it is in the upper third, in other screens the middle, still others the
   lower third".

   The middle of the window is the middle of the window. Taken out of the flow entirely, so nothing
   above it can move it and nothing about how tall the page is matters -- which is the only version
   of this that is the same on every screen.

   Transparent and untouchable: the page is still drawing its header behind this, and a full-window
   box that ate taps would make a bar that is visible unusable. */
.syc-brand-spinner-page {
    position: fixed;
    inset: 0;
    z-index: 1;

    display: grid;
    place-items: center;
    pointer-events: none;
}

/* The same wait on a screen whose controls fill the top half (Ideas): in the page's flow, so it
   sits in the empty space under them, roughly midway to the bottom bar -- never over them. */
.syc-brand-spinner-below {
    display: grid;
    place-items: center;
    min-height: 33dvh;
    pointer-events: none;
}

/* ── Holding a whole screen ───────────────────────────────────────────────────
   See BrandLoading. Over everything, including both bars, so the app arrives once rather than in
   pieces. 1100 clears the sheet backdrop at 1091, the highest thing on any screen. */
.syc-brand-loading {
    position: fixed;
    inset: 0;
    z-index: 1100;

    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1rem;

    /* Opaque, and the app's own ground rather than white -- the screen it is standing in for is
       not white, and the swap at the end should be the content appearing rather than the room
       changing colour around it. */
    background: var(--syc-bg, #fff);

    /* Under the notch and above the home indicator, like every other full-screen thing here. */
    padding: env(safe-area-inset-top, 0px) 1.5rem env(safe-area-inset-bottom, 0px);
}

.syc-brand-loading-heading {
    margin: 0;
    font-family: var(--syc-font-heading);
    font-size: 1.5rem;
    font-weight: 800;
    color: var(--syc-primary);
}

.syc-brand-loading-text {
    margin: 0;
    font-size: .95rem;
    color: var(--syc-text-muted);
    text-align: center;
}

/* ── The long wait ───────────────────────────────────────────────────────────
   A rail filling with clothes, for the one wait that is genuinely long: the first time the closet
   opens after signing in, and every time it is come back to.

   One swinging hanger is the right answer to a second and a half and the wrong answer to eight.
   Past a few seconds a mark that only marks time starts to read as a screen that has stopped, and
   what somebody wants to know is not that the app is busy but that it is busy doing their thing.
   So the rail fills, garment by garment, and says so in words.

   Drawn rather than fetched. An animated GIF of a closet being built is a file to make, a file to
   ship, a file to cache and a file that is wrong at every screen density; this is four copies of
   the mark the app already draws, on a timer. */
.syc-closet-building {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1.1rem;

    /* Arrives rather than replaces. The wait begins as the single hanger and becomes this only
       once it has gone on long enough to need saying -- see BrandLoading -- and a swap that
       happened instantly would be the screen changing its mind. */
    animation: syc-building-in .45s ease-out;
}

@keyframes syc-building-in {
    from { opacity: 0; transform: translateY(.5rem); }
    to { opacity: 1; transform: translateY(0); }
}

.syc-closet-rail { width: min(15rem, 70vw); height: auto; }

/* The rail itself, and the hook each garment hangs from. */
.syc-closet-rail-bar { stroke: var(--syc-accent, #EE5A3C); }
.syc-closet-rail-hanger { color: var(--syc-primary, #1F4A54); }

/* Each one arrives, hangs for a while, and the rail starts over. The stagger is what makes it
   read as filling rather than as four things blinking together. */
.syc-closet-rail-hanger > g {
    opacity: 0;
    animation: syc-closet-hang 3.2s ease-out infinite;
}

.syc-closet-rail-hanger:nth-child(2) > g { animation-delay: .25s; }
.syc-closet-rail-hanger:nth-child(3) > g { animation-delay: .5s; }
.syc-closet-rail-hanger:nth-child(4) > g { animation-delay: .75s; }
.syc-closet-rail-hanger:nth-child(5) > g { animation-delay: 1s; }

@keyframes syc-closet-hang {
    /* Down onto the rail, settled, and gone again so the next pass has somewhere to arrive. */
    0% { opacity: 0; transform: translateY(-10px); }
    12% { opacity: 1; transform: translateY(0); }
    78% { opacity: 1; transform: translateY(0); }
    92%, 100% { opacity: 0; transform: translateY(-10px); }
}

/* Still, for anybody who has asked for less movement: a full rail, which is the thing the
   animation was saying anyway. */
@media (prefers-reduced-motion: reduce) {
    .syc-closet-building { animation: none; }

    .syc-closet-rail-hanger > g {
        opacity: 1;
        animation: none;
    }
}

/* Page header */
.syc-page-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 1.5rem;
    padding-bottom: 1rem;
    border-bottom: 1px solid var(--syc-border);
}

/* Auth pages */
.syc-auth-container { max-width: 420px; margin: 3rem auto; }
.syc-auth-card {
    background: var(--syc-surface);
    border: 1px solid var(--syc-border);
    border-radius: var(--syc-radius-lg);
    box-shadow: var(--syc-shadow-lg);
    padding: 2.5rem;
}
.syc-auth-logo {
    text-align: center;
    margin-bottom: 1.5rem;
    color: var(--syc-accent);
    font-size: 2.5rem;
}
.syc-auth-title {
    font-family: var(--syc-font-heading);
    font-size: 1.75rem;
    font-weight: 400;
    text-align: center;
    margin-bottom: 0.25rem;
    color: var(--syc-primary);
}
.syc-auth-subtitle {
    text-align: center;
    color: var(--syc-text-muted);
    margin-bottom: 2rem;
    font-size: 0.9rem;
}
/* The 6-digit reset code. Monospaced and spaced out so digits are easy to check against the
   email, and large enough to type accurately on a phone. */
.syc-code-input {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 1.4rem;
    letter-spacing: 0.4em;
    text-align: center;
}
/* What the app is for, on the login card. Since login is now the first screen a visitor sees
   (there's no landing splash at "/" any more), this is the only place that still says it. */
.syc-auth-tagline {
    text-align: center;
    color: var(--syc-text-muted);
    margin-bottom: 2rem;
    font-size: 0.85rem;
    line-height: 1.5;
}

/* Admin stats */
.syc-admin-stats {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
    gap: 1rem;
    margin-bottom: 2rem;
}
.syc-stat-card {
    background: var(--syc-surface);
    border: 1px solid var(--syc-border);
    border-radius: var(--syc-radius-lg);
    padding: 1.25rem;
    text-align: center;
    border-top: 3px solid var(--syc-accent);
}
.syc-stat-number {
    font-family: var(--syc-font-heading);
    font-size: 2.5rem;
    font-weight: 400;
    color: var(--syc-primary);
    line-height: 1;
}
.syc-stat-label {
    font-size: 0.8rem;
    color: var(--syc-text-muted);
    margin-top: 0.25rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    font-weight: 500;
}

/* Table */
.syc-table { border-radius: var(--syc-radius); overflow: hidden; }
.syc-table thead { background-color: var(--syc-primary); color: #fff; }
.syc-table thead th { font-weight: 500; border: none; font-size: 0.85rem; letter-spacing: 0.03em; }

/* Image uploader */
.syc-image-uploader { width: 100%; }
.syc-image-preview { position: relative; display: inline-block; width: 100%; }
.syc-item-image {
    width: 100%;
    max-height: 320px;
    /* contain, not cover: cover would re-crop whatever the user just cropped, so a deliberate
       crop came back looking wrong. Letterboxing against the surface colour keeps the frame a
       steady size while showing the whole image. */
    object-fit: contain;
    background: var(--syc-surface-alt);
    border-radius: var(--syc-radius-lg);
    border: 1px solid var(--syc-border);
}
.syc-image-actions { display: flex; gap: 0.5rem; margin-top: 0.5rem; justify-content: center; }
.syc-image-placeholder {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    height: 220px;
    border: 2px dashed var(--syc-border);
    border-radius: var(--syc-radius-lg);
    background-color: var(--syc-surface-alt);
    cursor: pointer;
    color: var(--syc-text-muted);
    transition: all var(--syc-transition);
}
.syc-image-placeholder:hover {
    border-color: var(--syc-accent);
    color: var(--syc-accent-dark);
    background-color: var(--syc-accent-subtle);
}
.syc-image-placeholder i { font-size: 2rem; }
.syc-upload-overlay {
    position: absolute;
    top: 0; left: 0; right: 0; bottom: 0;
    background: rgba(255,255,255,0.85);
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--syc-radius-lg);
}
.syc-item-thumbnail { margin-bottom: 0.4rem; }
.syc-thumbnail-img {
    width: 72px;
    height: 72px;
    object-fit: cover;
    border-radius: var(--syc-radius);
    border: 1px solid var(--syc-border);
}

/* Multi-image gallery manager (ImageGalleryManager.razor) */
.syc-gallery-header { margin-bottom: 0.5rem; }
.syc-gallery-count { font-size: 0.85rem; color: var(--syc-text-muted); }
.syc-gallery-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    height: 140px;
    border: 2px dashed var(--syc-border);
    border-radius: var(--syc-radius-lg);
    background-color: var(--syc-surface-alt);
    color: var(--syc-text-muted);
}
.syc-gallery-empty i { font-size: 2rem; }
/* Photo carousel: one large photo per view, arrow-navigated (no peek). */
.syc-carousel { position: relative; overflow: hidden; border-radius: var(--syc-radius); }
.syc-carousel-track { display: flex; transition: transform 0.3s ease; }
.syc-carousel-slide {
    position: relative;
    flex: 0 0 100%;
    aspect-ratio: 1 / 1;
    /* Without a cap this square grows to the column width -- on a desktop that's a ~700px-tall
       photo that pushes every other field below the fold. On a phone the viewport is narrower
       than the cap, so it still fills the width. */
    max-height: 360px;
    overflow: hidden;
    border-radius: var(--syc-radius);
    border: 1px solid var(--syc-border);
    background: var(--syc-surface-alt);
}
.syc-carousel-slide.is-primary { border: 3px solid var(--syc-accent); }
/* zoom-in because tapping it opens the lightbox, which answers with zoom-out. Without the cursor
   nothing about the photograph says it can be tapped, and a feature nobody can see is not one. */
.syc-carousel-slide img { width: 100%; height: 100%; object-fit: contain; object-position: center; display: block; cursor: zoom-in; }
.syc-carousel-arrow {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 38px; height: 38px;
    border: none;
    border-radius: 50%;
    /* Dark with a white glyph: the slide letterboxes with object-fit: contain, so an arrow often
       sits over the pale surface colour rather than the photo. */
    background: rgba(0,0,0,0.55);
    color: #fff;
    font-size: 1.25rem;
    display: flex; align-items: center; justify-content: center;
    cursor: pointer;
    box-shadow: 0 1px 5px rgba(0,0,0,0.35);
    z-index: 2;
    transition: background var(--syc-transition);
}
.syc-carousel-arrow:hover:not(:disabled) { background: rgba(0,0,0,0.78); }
.syc-carousel-arrow:disabled { opacity: 0.3; cursor: default; }
.syc-carousel-arrow.prev { left: 8px; }
.syc-carousel-arrow.next { right: 8px; }
.syc-carousel-index {
    position: absolute;
    bottom: 8px; left: 50%;
    transform: translateX(-50%);
    background: rgba(0,0,0,0.55);
    color: #fff;
    font-size: 0.72rem;
    padding: 2px 9px;
    border-radius: 999px;
    z-index: 2;
}
.syc-carousel-setcover {
    position: absolute;
    bottom: 8px; left: 8px;
    border: none;
    border-radius: 999px;
    background: rgba(255,255,255,0.9);
    color: var(--syc-text);
    font-size: 0.72rem;
    padding: 3px 10px;
    cursor: pointer;
    z-index: 2;
    display: flex; align-items: center;
}
.syc-carousel-setcover:hover { background: #fff; }

/* Outfit ideas — a card per look, its pieces in a scrollable row */
.syc-outfit-card .syc-card-body { padding: 0.75rem 1rem; }
.syc-outfit-name { font-weight: 600; font-size: 1rem; color: var(--syc-text); margin-bottom: 0.15rem; }
.syc-outfit-label { font-size: 0.85rem; color: var(--syc-text-muted); margin-bottom: 0.5rem; }
.syc-outfit-caption { font-size: 0.85rem; color: var(--syc-text-muted); font-style: italic; margin-top: 0.5rem; }
/* Three across, wrapping down as the outfit grows. It used to scroll sideways, which hid the
   fourth piece behind a gesture nobody knew to make -- an outfit is a set, and a set you cannot
   see all of is not one. Wrapping rather than a fixed two rows, so a look with a coat and a bag
   grows a third row on its own. */
.syc-outfit-row {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 0.6rem;
}
.syc-outfit-piece { width: 100%; min-width: 0; text-align: center; }
.syc-outfit-piece img,
.syc-outfit-noimg {
    width: 100%;
    height: 120px;
    /* Show the whole garment (never crop) — tiles are portrait to suit clothing. */
    object-fit: contain;
    border-radius: var(--syc-radius);
    border: 1px solid var(--syc-border);
    background-color: var(--syc-surface-alt);
    display: block;
}
.syc-outfit-noimg {
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--syc-text-light);
    font-size: 1.5rem;
}
.syc-outfit-piece-name {
    display: block;
    font-size: 0.75rem;
    color: var(--syc-text-muted);
    margin-top: 0.25rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.syc-gallery-star {
    position: absolute;
    top: 4px; left: 4px;
    color: #e8b923;
    background: rgba(255,255,255,0.85);
    border-radius: 50%;
    width: 22px; height: 22px;
    display: flex; align-items: center; justify-content: center;
    font-size: 0.8rem;
}
/* The row of controls on a saved photo.

   A flex row, not five buttons each given a right: offset counted by hand. The hand-counted
   version worked exactly until a sixth button was added: a second rotate control shared the
   rotate class, landed on the same offset, and painted directly on top of the first, so only one
   of the two could ever be seen. Which button sits where is now a consequence of the order they
   are written in, and adding one costs nothing. */
.syc-gallery-actions {
    position: absolute;
    top: 4px;
    right: 4px;
    display: flex;
    gap: 6px;
    z-index: 3;
}

/* Crop control on a saved photo. Same shape as its neighbours, so the row reads as one group. */
.syc-gallery-crop {
    width: 24px; height: 24px;
    padding: 0;
    display: flex; align-items: center; justify-content: center;
    border: none;
    border-radius: 50%;
    background: rgba(255,255,255,0.9);
    color: var(--syc-primary);
    font-size: 0.8rem;
    cursor: pointer;
    transition: background var(--syc-transition);
}

.syc-gallery-crop:hover { background: #fff; }
.syc-gallery-crop:disabled { opacity: 0.5; cursor: default; }

/* Turn a photo a quarter, one button each way. Both share this class now that the row places
   itself -- which is the point of the change. */
.syc-gallery-rotate {
    width: 24px; height: 24px;
    padding: 0;
    display: flex; align-items: center; justify-content: center;
    border: none;
    border-radius: 50%;
    background: rgba(255,255,255,0.9);
    color: var(--syc-text);
    box-shadow: 0 1px 3px rgba(0,0,0,0.25);
    font-size: 0.7rem;
    cursor: pointer;
}

.syc-gallery-rotate:hover { background: #fff; }
.syc-gallery-rotate:disabled { opacity: 0.5; cursor: default; }

/* Cut out the background. */
.syc-gallery-cutout {
    width: 24px; height: 24px;
    padding: 0;
    display: flex; align-items: center; justify-content: center;
    border: none;
    border-radius: 50%;
    background: rgba(255,255,255,0.9);
    color: var(--syc-text);
    box-shadow: 0 1px 3px rgba(0,0,0,0.25);
    font-size: 0.7rem;
    cursor: pointer;
}

.syc-gallery-cutout:hover { background: #fff; }
.syc-gallery-cutout:disabled { opacity: 0.5; cursor: default; }

/* Undo crop. Only appears on a photo that has actually been cropped — a permanent button on every
   photo would be noise for the common case. */
.syc-gallery-revert {
    width: 24px; height: 24px;
    padding: 0;
    display: flex; align-items: center; justify-content: center;
    border: none;
    border-radius: 50%;
    background: rgba(255,255,255,0.9);
    color: var(--syc-text);
    font-size: 0.8rem;
    cursor: pointer;
    transition: background var(--syc-transition);
}
.syc-gallery-revert:hover { background: #fff; }
.syc-gallery-revert:disabled { opacity: 0.5; cursor: default; }

.syc-gallery-delete {
    width: 24px; height: 24px;
    padding: 0;
    display: flex; align-items: center; justify-content: center;
    border: none;
    border-radius: 50%;
    background: rgba(255,255,255,0.9);
    color: var(--syc-danger);
    font-size: 0.8rem;
    cursor: pointer;
    transition: background var(--syc-transition);
}
.syc-gallery-delete:hover { background: var(--syc-danger); color: #fff; }
.syc-gallery-delete:disabled { opacity: 0.5; cursor: default; }

/* ======================================   Wardrobe Profiles
   ============================================= */

/* Profile selector in welcome bar */
.syc-profile-selector { position: relative; display: inline-block; }

.syc-profile-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    background: transparent;
    border: 1px solid var(--syc-border);
    border-radius: var(--syc-radius);
    padding: 0.25rem 0.75rem;
    font-size: 0.82rem;
    color: var(--syc-text);
    cursor: pointer;
    transition: all var(--syc-transition);
}

.syc-profile-btn:hover {
    background: var(--syc-surface-alt);
    border-color: var(--syc-primary);
}

.syc-profile-menu {
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    min-width: 240px;
    background: var(--syc-surface);
    border: 1px solid var(--syc-border);
    border-radius: var(--syc-radius-lg);
    box-shadow: var(--syc-shadow-lg);
    z-index: 500;
    overflow: hidden;
}

.syc-profile-menu-item {
    display: flex;
    align-items: center;
    width: 100%;
    padding: 0.65rem 1rem;
    font-size: 0.875rem;
    color: var(--syc-text);
    background: transparent;
    border: none;
    text-decoration: none;
    transition: background var(--syc-transition);
    cursor: pointer;
    gap: 0.5rem;
}

.syc-profile-menu-item:hover {
    background: var(--syc-surface-alt);
    color: var(--syc-text);
    text-decoration: none;
}

.syc-profile-menu-item.active {
    background: var(--syc-accent-subtle);
    color: var(--syc-primary);
    font-weight: 500;
}

.syc-profile-menu-item small {
    color: var(--syc-text-muted);
    font-size: 0.75rem;
    margin-left: auto;
}

.syc-profile-menu-divider {
    height: 1px;
    background: var(--syc-border);
    margin: 0.25rem 0;
}

/* Onboarding / Profile Create */
.syc-onboarding-container {
    max-width: 640px;
    margin: 0 auto 2rem;   /* sits up near the top (syc-main already adds top padding) */
    padding: 0 1rem;
}

.syc-onboarding-step {
    background: var(--syc-surface);
    border: 1px solid var(--syc-border);
    border-radius: var(--syc-radius-lg);
    padding: 2rem;
    margin-bottom: 1.5rem;
}

.syc-onboarding-step h2 {
    font-family: var(--syc-font-heading);
    font-size: 1.4rem;
    font-weight: 400;
    color: var(--syc-primary);
    margin-bottom: 1.25rem;
}

/* Choice grid */
.syc-choice-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(130px, 1fr));
    gap: 0.75rem;
}

.syc-choice-card {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.35rem;
    padding: 0.875rem 0.75rem;
    background: var(--syc-surface-alt);
    border: 2px solid var(--syc-border);
    border-radius: var(--syc-radius-lg);
    cursor: pointer;
    text-align: center;
    font-size: 0.875rem;
    color: var(--syc-text);
    transition: all var(--syc-transition);
    user-select: none;
}

.syc-choice-card small {
    font-size: 0.72rem;
    color: var(--syc-text-muted);
    line-height: 1.3;
}

.syc-choice-card:hover {
    border-color: var(--syc-accent);
    background: var(--syc-accent-subtle);
}

.syc-choice-card.selected {
    border-color: var(--syc-primary);
    background: var(--syc-accent-subtle);
    color: var(--syc-primary);
    font-weight: 500;
}

.syc-choice-card i {
    font-size: 1.4rem;
    color: var(--syc-primary);
}

/* Occasion chips */
.syc-occasion-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.syc-chip {
    display: inline-flex;
    align-items: center;
    padding: 0.35rem 0.875rem;
    border: 1.5px solid var(--syc-border);
    border-radius: 20px;
    background: var(--syc-surface);
    font-size: 0.8rem;
    color: var(--syc-text-muted);
    cursor: pointer;
    transition: all var(--syc-transition);
    user-select: none;
}

.syc-chip:hover {
    border-color: var(--syc-accent);
    background: var(--syc-accent-subtle);
    color: var(--syc-text);
}

/* Solid Deep Teal, as the brand guide's selected chip; the Tint is the hover. */
.syc-chip.selected {
    border-color: var(--syc-primary);
    background: var(--syc-primary);
    color: #fff;
    font-weight: 600;
}

/* Subtype filter chips (My Closet browse) */
.syc-subtype-filter {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-bottom: 1.25rem;
}

.syc-subtype-filter .syc-chip {
    font-size: 0.78rem;
    padding: 0.3rem 0.75rem;
}

.syc-subtype-filter .chip-count {
    margin-left: 0.4rem;
    opacity: 0.6;
    font-size: 0.72rem;
}

/* Save/Cancel bar for the long add/edit forms. Sticks to the bottom of the viewport while
   the form is still scrolling past, so the primary action is never out of reach — three beta
   testers independently asked for Save to be at an edge rather than mid-page (#121). Lives
   inside the <EditForm> so the submit button still submits. */
.syc-form-actions {
    position: sticky;
    bottom: 0;
    z-index: 20;
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    padding: 0.75rem 0;
    /* Clear the home indicator on iPhones; resolves to 0 everywhere else. */
    padding-bottom: calc(0.75rem + env(safe-area-inset-bottom, 0px));
    background: var(--syc-surface);
    border-top: 1px solid var(--syc-border);
}

/* Extra-photo strip on the add form (AdditionalPhotos). Thumbnails scroll sideways rather than
   wrapping, so the form's vertical rhythm doesn't change as photos are added. */
.syc-extra-photos-strip {
    display: flex;
    gap: 0.5rem;
    overflow-x: auto;
    padding-bottom: 0.25rem;
}

.syc-extra-photo {
    position: relative;
    flex: 0 0 auto;
    width: 72px;
    height: 72px;
    border-radius: 8px;
    overflow: hidden;
    border: 1px solid var(--syc-border);
}

.syc-extra-photo img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.syc-extra-photo-remove {
    position: absolute;
    top: 2px;
    right: 2px;
    width: 20px;
    height: 20px;
    line-height: 1;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.55);
    color: #fff;
    font-size: 1rem;
    cursor: pointer;
}

/* Cropper overlay (crop.js). Full-screen so the gesture has room on a phone; the crop box and
   its handles are sized for a fingertip rather than a mouse. */
.syc-crop-root {
    position: fixed;
    inset: 0;
    /* Above the dialogs (1211): the sample-closet editor is a dialog, and opens the cropper from
       inside it. At 1080 the crop frame was drawn underneath the form -- reported with a
       screenshot of the handles showing round its edges. See the ladder at .syc-sheet-backdrop. */
    z-index: 1220;
    background: rgba(0, 0, 0, 0.85);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
    padding-bottom: calc(1rem + env(safe-area-inset-bottom, 0px));
}

.syc-crop-dialog {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    max-width: 100%;
    max-height: 100%;
}

.syc-crop-stage {
    position: relative;
    display: flex;
    justify-content: center;
    /* Not the default stretch: a flex row stretches an <img> vertically, object-fit then
       letterboxes the picture inside a taller element, and the cropper ends up measuring the
       element instead of the photo. crop.js computes the real picture box regardless, but the
       distortion shouldn't be there in the first place. */
    align-items: center;
    min-height: 0;
}

.syc-crop-img {
    max-width: 100%;
    max-height: 70vh;
    object-fit: contain;
    user-select: none;
    -webkit-user-drag: none;
}

.syc-crop-box {
    position: absolute;
    border: 2px solid #fff;
    box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.45);
    cursor: move;
    touch-action: none;   /* the gesture is ours, not the page's */
}

.syc-crop-box span {
    position: absolute;
    width: 22px;
    height: 22px;
    background: #fff;
    border-radius: 50%;
    touch-action: none;
}

.syc-crop-box span[data-h="nw"] { top: -11px; left: -11px; cursor: nwse-resize; }
.syc-crop-box span[data-h="ne"] { top: -11px; right: -11px; cursor: nesw-resize; }
.syc-crop-box span[data-h="sw"] { bottom: -11px; left: -11px; cursor: nesw-resize; }
.syc-crop-box span[data-h="se"] { bottom: -11px; right: -11px; cursor: nwse-resize; }

.syc-crop-bar {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    justify-content: center;
}

/* Searchable select (typeahead) */
.syc-typeahead {
    position: relative;
}

.syc-typeahead-control {
    position: relative;
}

.syc-typeahead-control .form-control {
    padding-right: 2rem;
}

.syc-typeahead-clear {
    position: absolute;
    right: 0.6rem;
    top: 50%;
    transform: translateY(-50%);
    border: none;
    background: transparent;
    color: var(--syc-text-muted);
    font-size: 1.15rem;
    line-height: 1;
    padding: 0;
    cursor: pointer;
}

.syc-typeahead-clear:hover {
    color: var(--syc-text);
}

.syc-typeahead-menu {
    position: absolute;
    z-index: 30;
    top: calc(100% + 2px);
    left: 0;
    right: 0;
    margin: 0;
    padding: 0.25rem 0;
    list-style: none;
    background: var(--syc-surface);
    border: 1px solid var(--syc-border);
    border-radius: 8px;
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.12);
    max-height: 240px;
    overflow-y: auto;
}

.syc-typeahead-item {
    padding: 0.45rem 0.875rem;
    font-size: 0.9rem;
    color: var(--syc-text);
    cursor: pointer;
}

.syc-typeahead-item:hover,
.syc-typeahead-item.active {
    background: var(--syc-accent-subtle);
    color: var(--syc-primary);
}

.syc-typeahead-other {
    border-top: 1px solid var(--syc-border);
    font-style: italic;
}

.syc-typeahead-empty {
    padding: 0.45rem 0.875rem;
    font-size: 0.85rem;
    color: var(--syc-text-muted);
}

/* Step indicator and nav */
.syc-onboarding-nav {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-top: 1rem;
}

.syc-step-indicator {
    display: flex;
    gap: 0.5rem;
    justify-content: center;
    margin-top: 1.25rem;
}

.syc-step-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--syc-border);
    transition: all var(--syc-transition);
}

.syc-step-dot.active {
    background: var(--syc-primary);
    transform: scale(1.3);
}

.syc-step-dot.done {
    background: var(--syc-accent);
}

/* Profile list cards */
.syc-profile-card {
    background: var(--syc-surface);
    border: 1px solid var(--syc-border);
    border-radius: var(--syc-radius-lg);
    padding: 1.25rem;
    display: flex;
    align-items: center;
    gap: 1rem;
    transition: box-shadow var(--syc-transition);
}

.syc-profile-card:hover {
    box-shadow: var(--syc-shadow-lg);
}

.syc-profile-card-icon {
    width: 48px;
    height: 48px;
    border-radius: 50%;
    background: var(--syc-accent-subtle);
    border: 1px solid var(--syc-accent-light);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.25rem;
    color: var(--syc-accent-dark);
    flex-shrink: 0;
}

.syc-profile-card-info { flex: 1; min-width: 0; }

.syc-profile-card-name {
    font-weight: 600;
    font-size: 0.95rem;
    color: var(--syc-text);
    margin-bottom: 0.2rem;
}

.syc-profile-card-meta {
    font-size: 0.8rem;
    color: var(--syc-text-muted);
    margin-bottom: 0.1rem;
}

.syc-profile-card-actions {
    display: flex;
    gap: 0.5rem;
    flex-shrink: 0;
}

.syc-badge-default {
    background: var(--syc-accent-subtle);
    color: var(--syc-accent-dark);
    border: 1px solid var(--syc-accent-light);
    border-radius: 20px;
    padding: 0.1rem 0.5rem;
    font-size: 0.7rem;
    font-weight: 500;
}

/* Welcome bar layout with profile selector */
.syc-welcome-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
}

.syc-welcome-text {
    font-size: 0.85rem;
    color: var(--syc-text-muted);
}

/* ======================================   Wardrobe Analysis
   ============================================= */

/* Score card */
.syc-score-card {
    background: var(--syc-surface);
    border: 1px solid var(--syc-border);
    border-radius: var(--syc-radius-lg);
    padding: 1.5rem;
}

.syc-score-inner {
    display: flex;
    align-items: center;
    gap: 1.5rem;
}

.syc-score-circle {
    position: relative;
    width: 90px;
    height: 90px;
    flex-shrink: 0;
}

.syc-score-svg {
    width: 90px;
    height: 90px;
    transform: rotate(-90deg);
}

.syc-score-bg {
    stroke: var(--syc-border);
}

.syc-score-fill {
    stroke: var(--syc-primary);
    stroke-linecap: round;
    transition: stroke-dasharray 0.6s ease;
}

.syc-score-number {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    font-family: var(--syc-font-heading);
    font-size: 1.3rem;
    font-weight: 400;
    color: var(--syc-primary);
}

.syc-score-label {
    font-family: var(--syc-font-heading);
    font-size: 1.1rem;
    font-weight: 400;
    color: var(--syc-text);
    margin-bottom: 0.25rem;
}

.syc-score-sub {
    font-size: 0.875rem;
    color: var(--syc-text-muted);
    margin-bottom: 0.25rem;
}

.syc-score-surplus {
    font-size: 0.8rem;
    color: var(--syc-warning);
    margin: 0;
}

/* Section title */
.syc-section-title {
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--syc-text-muted);
    margin-bottom: 0.75rem;
    padding-bottom: 0.4rem;
    border-bottom: 1px solid var(--syc-border);
    display: flex;
    align-items: center;
    justify-content: space-between;
}

/* "Based on your profile" callout — highlighted so it catches the eye */
.syc-analysis-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
}
.syc-profile-basis {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    flex: 1;
    min-width: 260px;
    padding: 0.75rem 1rem;
    background: var(--syc-accent-subtle);
    border: 1px solid var(--syc-accent-light);
    border-left: 4px solid var(--syc-accent);
    border-radius: var(--syc-radius);
}
.syc-profile-basis-icon { font-size: 1.4rem; color: var(--syc-accent-dark); }
.syc-profile-basis-label {
    font-weight: 700;
    font-size: 0.7rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--syc-accent-dark);
}
.syc-profile-basis-values { font-size: 0.9rem; color: var(--syc-text); }

.syc-glance-score {
    font-size: 0.85rem;
    font-weight: 700;
    color: var(--syc-accent-dark);
    background: var(--syc-accent-subtle);
    border-radius: 999px;
    padding: 0.1rem 0.7rem;
    text-transform: none;
    letter-spacing: 0;
}

/* Glance cards — click to expand a by-clothing-type breakdown */
.syc-glance {
    height: 100%;
    background: var(--syc-surface);
    border: 1px solid var(--syc-border);
    border-radius: var(--syc-radius-lg);
    overflow: hidden;
    transition: box-shadow var(--syc-transition), border-color var(--syc-transition);
}
.syc-glance[open] { border-color: var(--syc-accent); box-shadow: var(--syc-shadow-lg); }
.syc-glance-summary {
    list-style: none;
    cursor: pointer;
    padding: 1.25rem 1rem;
    text-align: center;
}
.syc-glance-summary::-webkit-details-marker { display: none; }
.syc-glance-chevron {
    font-size: 0.75rem;
    color: var(--syc-text-muted);
    transition: transform 0.15s ease;
}
.syc-glance[open] .syc-glance-chevron { transform: rotate(180deg); }
.syc-glance-body {
    border-top: 1px solid var(--syc-border);
    padding: 0.5rem 1rem 0.75rem;
}
.syc-glance-row {
    display: flex;
    justify-content: space-between;
    padding: 0.3rem 0;
    font-size: 0.85rem;
    border-bottom: 1px solid var(--syc-border);
}
.syc-glance-row:last-child { border-bottom: none; }

/* Collapsible toggle panels (What You Need / By Occasion / Consider Donating) */
.syc-collapse-panel {
    border: 1px solid var(--syc-border);
    border-radius: var(--syc-radius);
    background: var(--syc-surface);
    overflow: hidden;
}
.syc-collapse-btn {
    list-style: none;
    cursor: pointer;
    display: flex;
    align-items: center;
    padding: 0.7rem 1rem;
    font-weight: 700;
    font-size: 0.95rem;
    color: var(--syc-primary);
    background: var(--syc-surface-alt);
}
.syc-collapse-btn::-webkit-details-marker { display: none; }
.syc-collapse-btn::after {
    content: "\25BE";
    margin-left: auto;
    color: var(--syc-text-muted);
    transition: transform 0.15s ease;
}
.syc-collapse-panel[open] > .syc-collapse-btn::after { transform: rotate(180deg); }
.syc-collapse-content { padding: 1rem; }
.syc-collapse-content.p-0 { padding: 0; }

/* Comparison grid */
.syc-comparison-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
    gap: 0.75rem;
}

.syc-comparison-card {
    background: var(--syc-surface);
    border: 1px solid var(--syc-border);
    border-radius: var(--syc-radius-lg);
    padding: 0.875rem;
    border-top: 3px solid var(--syc-border);
}

.syc-comparison-card.missing {
    border-top-color: var(--syc-danger);
}

.syc-comparison-card.surplus {
    border-top-color: var(--syc-warning);
}

.syc-comparison-card.complete {
    border-top-color: var(--syc-success);
}

.syc-comparison-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 0.5rem;
}

.syc-comparison-type {
    font-weight: 600;
    font-size: 0.875rem;
    color: var(--syc-text);
    text-transform: capitalize;
}

.syc-comparison-bar {
    height: 6px;
    background: var(--syc-border);
    border-radius: 3px;
    margin-bottom: 0.4rem;
    overflow: hidden;
}

.syc-bar-fill {
    height: 100%;
    background: var(--syc-primary);
    border-radius: 3px;
    transition: width 0.6s ease;
    max-width: 100%;
}

.syc-comparison-counts {
    display: flex;
    justify-content: space-between;
    font-size: 0.75rem;
    color: var(--syc-text-muted);
}

/* Suggestions */
.syc-suggestion-group {
    background: var(--syc-surface);
    border: 1px solid var(--syc-border);
    border-radius: var(--syc-radius-lg);
    overflow: hidden;
}

.syc-suggestion-header {
    padding: 0.6rem 1rem;
    font-size: 0.8rem;
    font-weight: 600;
    background: var(--syc-surface-alt);
    border-bottom: 1px solid var(--syc-border);
    display: flex;
    align-items: center;
}

.syc-suggestion-item {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.65rem 1rem;
    border-bottom: 1px solid var(--syc-border);
    font-size: 0.875rem;
}

.syc-suggestion-item:last-child {
    border-bottom: none;
}

.syc-suggestion-qty {
    font-weight: 700;
    font-size: 0.9rem;
    color: var(--syc-primary);
    min-width: 28px;
}

.syc-suggestion-desc {
    color: var(--syc-text);
    flex: 1;
}

/* ── Color picker with "add your own" ──────────────────────────────────────── */
/* The add row sits under the select rather than replacing it, so the existing
   palette stays visible while someone types a name. */
.syc-color-add {
    margin-top: 0.35rem;
}
.syc-color-add .form-control-color {
    max-width: 3rem;
    padding: 0.2rem;
}
.syc-color-add-error {
    margin-top: 0.25rem;
    font-size: 0.8rem;
    color: var(--syc-danger, #8B3330);
}

/* ── Bulk add review rows (BulkAddItems) ───────────────────────────────────── */
/* One row per pending item: thumbnail, the two fields that must be right before saving, and a
   remove button. Deliberately denser than the single-item form — the point of the screen is to
   scan a batch, not to fill anything in properly. */
.syc-bulk-row {
    display: flex;
    gap: 0.75rem;
    align-items: flex-start;
    padding: 0.75rem 0;
    border-bottom: 1px solid var(--syc-border);
}
.syc-bulk-row:last-of-type {
    border-bottom: none;
}
/* A row still missing a name or type gets a left edge rather than a full highlight, so a batch
   with two problems doesn't read as a page full of errors. */
.syc-bulk-row.needs-attention {
    border-left: 3px solid var(--syc-danger, #8B3330);
    padding-left: 0.5rem;
}
.syc-bulk-thumb {
    width: 64px;
    height: 64px;
    flex: 0 0 64px;
    object-fit: cover;
    border-radius: var(--syc-radius-sm, 6px);
    background: var(--syc-surface-alt, #f2f2f2);
}
.syc-bulk-fields {
    flex: 1 1 auto;
    min-width: 0;
}

/* ── Closet view toggle (All items / Grouped) ──────────────────────────────── */
/* Sits between the scope pills and the subtype chips. Reuses .syc-chip so it reads as another
   filter row rather than introducing a third control style. */
.syc-view-toggle {
    display: flex;
    gap: 0.4rem;
    margin-bottom: 0.75rem;
}

/* The overlay shown while photographs are read off the file input on the closet screen. Covering
   the page is deliberate: the picked files are being read one at a time and a second tap during
   that would start a competing batch. */
.syc-reading-overlay {
    position: fixed;
    inset: 0;
    z-index: 1090;
    background: rgba(0, 0, 0, 0.45);
    display: flex;
    align-items: center;
    justify-content: center;
}

.syc-reading-panel {
    background: var(--syc-surface);
    color: var(--syc-text);
    border-radius: var(--syc-radius-lg, 12px);
    padding: 1.5rem 2rem;
    text-align: center;
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.28);
}

/* ======================================   Item detail, read view (#188)
   ============================================= */

/* The name is the heading now, so it carries the weight a label used to. Bigger than the form's
   input, because reading it is the whole job of the page. */
.syc-read-name {
    /* Down from 1.5rem. Long names -- and the photo analysis writes long ones, "Brown
       Double-Breasted Blazer Vest" -- wrapped to three lines and pushed the details off the
       screen. It is a label for the picture above it, not a headline. */
    font-size: 1.25rem;
    font-weight: 600;
    line-height: 1.25;
    margin: 0 0 0.35rem;
    color: var(--syc-text);
}

/* Subtype · colour · size · brand on one line. No labels: a size reads as a size. */
.syc-read-summary {
    font-size: 1.05rem;
    color: var(--syc-text-muted);
    margin: 0 0 0.75rem;
}

.syc-read-description {
    font-size: 1rem;
    line-height: 1.5;
    margin: 0 0 0.9rem;
    color: var(--syc-text);
}

.syc-read-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
    margin-bottom: 0.6rem;
}

/* Only what was chosen appears, so these are statements rather than controls — no checkbox
   affordance, nothing to suggest tapping one does something. */
.syc-read-tag {
    font-size: 0.85rem;
    padding: 0.15rem 0.6rem;
    border-radius: 999px;
    background: var(--syc-surface-alt);
    border: 1px solid var(--syc-border);
    color: var(--syc-text);
}

.syc-read-tag-weather {
    background: transparent;
}

.syc-card-photo-wrap { position: relative; }

/* Keeping a generated outfit (#196). Suggestions are computed from a seed, so shuffling loses
   them — the action sits under the pieces, where the decision is actually made. */
.syc-outfit-actions {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-top: 0.6rem;
}

/* Already kept. A statement, not a control: nothing to press, nothing to undo by accident. */
.syc-outfit-saved {
    font-size: 0.85rem;
    color: var(--syc-text-muted);
}

/* ======================================   My outfits: saved looks and wear history (#196, #197)
   ============================================= */

/* A piece that has left the closet since the outfit was saved. Stated rather than left as a
   shorter row — a look quietly missing a piece reads as one that never had it. */
.syc-outfit-missing {
    font-size: 0.85rem;
    color: var(--syc-text-muted);
    margin: 0.4rem 0 0;
}

.syc-wear-day {
    margin-bottom: 1.25rem;
}

/* The date leads, because the question is "what did I wear on the Saturday" — the garments are
   the answer, not the index. */
.syc-wear-date {
    font-weight: 600;
    font-size: 0.95rem;
    margin-bottom: 0.4rem;
    color: var(--syc-text);
}

/* Duplicate review (#211). Side by side, because the question is a comparison — a list would make
   the reader hold both in their head, which is the manual review this replaces. */
.syc-dupe-row {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
}

/* Fixed columns rather than flexible ones. Flexible basis let a pair wrap onto separate rows on a
   phone, and two garments stacked a screen apart are not a comparison -- which is the only thing
   this screen is for. Side by side always, narrower rather than wrapped. */
.syc-dupe-row {
    flex-wrap: nowrap;
    align-items: flex-start;
}

.syc-dupe-item {
    flex: 1 1 0;
    min-width: 0;
    max-width: 50%;
    text-align: center;
}

.syc-dupe-item img {
    width: 100%;
    /* Portrait, because garments are. A square box letterboxed a standing garment into a stripe
       through the middle and wasted the height that makes it recognisable. */
    aspect-ratio: 3 / 4;
    object-fit: contain;
    background: var(--syc-surface-alt);
    border-radius: var(--syc-radius);
}

.syc-dupe-name {
    font-weight: 600;
    font-size: 0.9rem;
    margin-top: 0.4rem;
}

/* Shown because the names and descriptions differ even for the same photo — which is the strongest
   sign to a reader that these are one garment entered twice. */
.syc-dupe-desc {
    font-size: 0.8rem;
    color: var(--syc-text-muted);
}

/* Says whether a pair is a fact or a guess (#211). One is "these files are identical"; the other is
   "these might be the same garment" — showing them identically would overstate the second. */
.syc-dupe-kind {
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--syc-text-muted);
    margin-bottom: 0.6rem;
}

/* The distance readout (#211). Collapsed by default: it explains an answer rather than being one. */
/* One line saying what the two buttons do. "Delete this one" and "Keep both" are each clear alone
   and ambiguous together — it was not obvious that keeping both was an option at all. */
.syc-dupe-help {
    font-size: 0.85rem;
    color: var(--syc-text-muted);
    margin: 0.6rem 0 0;
}

/* The distance beside the "different garments" button. Deliberately quiet: it is evidence for
   anyone tuning the threshold later, not something a person deciding about two shirts should
   have to read. */
.syc-dupe-distance {
    font-size: 0.78rem;
    color: var(--syc-text-muted);
    font-family: monospace;
    align-self: center;
}

/* A heading between the certain pairs and the uncertain ones. */
.syc-section-title {
    font-size: 1.05rem;
    font-weight: 600;
    color: var(--syc-text);
    margin: 1.75rem 0 0.35rem;
}

/* The count beside a section heading. Same shape as the closet's pill counts, so a number in a
   heading reads as the same kind of thing it does on a filter. */
.syc-section-count {
    display: inline-block;
    min-width: 1.4rem;
    padding: 0.05rem 0.4rem;
    border-radius: 999px;
    background: var(--syc-surface-alt);
    color: var(--syc-text-muted);
    font-size: 0.8rem;
    font-weight: 600;
    text-align: center;
    vertical-align: middle;
}

/* ── The bottom tab bar (BottomNav) ────────────────────────────────────────────
   Four destinations along the bottom edge, the shape both of the apps the owner named use. Fixed
   rather than scrolling with the page: the point is that it is in the same place on every screen,
   so nothing has to be scrolled back to.

   Phones only. Above 992px the side navigation already answers this and the bottom edge of a
   desktop window is a long way from the pointer. */
/* Floating, with the page running underneath it.

   It was a full-width bar welded to the bottom edge with a line above it, which reads as the floor
   of the app -- the page stops there. Lifted off the edge and rounded, it reads as a control that
   travels with you over content that continues behind it, which is what it is. Modelled on the
   apps the owner reaches for without thinking.

   The lift has to be matched by the padding under .syc-main below, or the last garment in the grid
   ends up behind it. */
/* Pinned to the bottom edge rather than floating above it.

   It floated for a while -- a rounded pill inset from the edges with a shadow under it -- and was
   reported as confusing: a bar that hovers reads as something over the page rather than part of
   it, and the gap underneath looks like content that has been cut off. Pinned, it is the floor. */
.syc-tabbar {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    padding-block-end: env(safe-area-inset-bottom, 0px);
    z-index: 1035;
    display: flex;
    background: var(--syc-surface);
    border-block-start: 1px solid var(--syc-border);

    /* Upward only, and shallow. A pinned bar needs to separate itself from what scrolls under it,
       not to look lifted off the screen. */
    box-shadow: 0 -2px 10px rgba(0, 0, 0, .06);
}

.syc-tab {
    flex: 1 1 0;
    min-width: 0;

    /* They are anchors, and on the phone they were coming out underlined -- five underlined words
       along the bottom of every screen. The bar was buttons when this rule was not needed. */
    text-decoration: none;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.1rem;
    /* 56px plus the label keeps every tab a comfortable thumb target. */
    padding: 0.45rem 0.25rem 0.5rem;
    border: none;
    background: none;
    color: var(--syc-text-muted);
    cursor: pointer;
    transition: color var(--syc-transition);
}

.syc-tab .bi {
    font-size: 1.3rem;
    line-height: 1;
}

.syc-tab-label {
    font-size: 0.68rem;
    font-weight: 600;
    letter-spacing: 0.01em;
    /* A truncated label is worse than a short one, so the names are short. */
    white-space: nowrap;
}

.syc-tab.active {
    color: var(--syc-primary);
}

.syc-tab:focus-visible {
    outline: 2px solid var(--syc-accent);
    outline-offset: -2px;
}

/* Room for the bar, so the last garment in the grid is never sitting behind it. The floating add
   button lifts by the same amount. */
@media (max-width: 991.98px) {
    /* Room for the bar plus the gap it now floats in, so the last garment in the grid is never
       sitting behind it. The floating button lifts by the same amount. */
    .maui-main,
    .syc-main {
        padding-bottom: calc(84px + env(safe-area-inset-bottom, 0px));
    }

    .syc-fab {
        bottom: calc(92px + env(safe-area-inset-bottom, 0px));
    }
}

@media (min-width: 992px) {
    .syc-tabbar { display: none; }
}

/* One row that scrolls sideways, rather than two or three that stack.

   Wrapping pills pushed the first garment below the fold on a phone -- five filters became three
   rows of chrome before any content. Sideways is how a phone shows a list that does not fit, and
   it keeps the grid where the eye lands. */
.filter-pills {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
    padding-bottom: 0.25rem;
}

.filter-pills::-webkit-scrollbar { display: none; }

.filter-pills .pill {
    flex: 0 0 auto;
}

/* Back, and stepping to the next garment: all three are ways of leaving this screen, so they sit
   together in the header rather than under the description. */
.syc-item-header-actions {
    display: flex;
    align-items: center;
    gap: 0.4rem;
}

/* Back does a different thing from the two arrows beside it -- out, rather than along -- and
   flush against them it read as a third arrow in the same row. A gap and a hairline say so. */
.syc-item-header-actions .syc-item-back {
    margin-left: 0.5rem;
    padding-left: 0.75rem;
    border-left: 1px solid var(--syc-border);
}

/* The "4 of 31" between the two stepping arrows. Narrow and quiet: the header is crowded, and the
   number is context rather than a control. */
.syc-item-step-count {
    font-size: 0.78rem;
    color: var(--syc-text-muted);
    white-space: nowrap;
}

/* ── Selecting several items (#215) ───────────────────────────────────────────
   The mode switch sits above the filters, because it changes what a tap on the grid means rather
   than what the grid contains. */
.syc-closet-modes {
    display: flex;
    gap: 0.4rem;
    margin-bottom: 0.6rem;
}

/* The tick on a card while selecting. Top-left, opposite the photo controls, so nothing sits on
   top of anything. */
.syc-item-tick {
    position: absolute;
    top: 6px;
    left: 6px;
    z-index: 6;
    font-size: 1.25rem;
    line-height: 1;
    color: var(--syc-primary);
    /* Reads on a pale garment and a dark one alike, without a border that would look tappable in
       its own right. */
    text-shadow: 0 0 3px rgba(255, 255, 255, 0.95), 0 1px 2px rgba(0, 0, 0, 0.3);
}

.syc-item-card.is-picked {
    outline: 3px solid var(--syc-primary);
    outline-offset: -3px;
}

/* Above the tab bar, not at the top of the page: a selection is made by scrolling and tapping, so
   the count and the button have to stay under the thumb. */
.syc-select-bar {
    position: fixed;
    left: 0;
    right: 0;
    bottom: calc(66px + env(safe-area-inset-bottom, 0px));
    z-index: 1036;
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.6rem 1rem;
    background: var(--syc-surface);
    border-top: 1px solid var(--syc-border);
    box-shadow: 0 -2px 12px rgba(0, 0, 0, 0.10);
}

.syc-select-count {
    flex: 1 1 auto;
    font-weight: 600;
    font-size: 0.9rem;
    color: var(--syc-text);
}

@media (min-width: 992px) {
    /* No tab bar on a wide screen, so the bar sits on the bottom edge itself. */
    .syc-select-bar { bottom: 0; }
}

/* The confirmation. Centred rather than a bottom sheet: it is a question that stops everything,
   and it should not look like one more thing along the bottom. */
.syc-confirm {
    position: fixed;

    /* With .syc-look, and for the same reason: it shares .syc-sheet-backdrop, so it moves when
       that moves or it ends up behind its own shade. See the ladder there. */
    z-index: 1211;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    width: 340px;
    max-width: calc(100vw - 2rem);
    background: var(--syc-surface);
    border-radius: var(--syc-radius-lg, 12px);
    padding: 1.25rem;
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.28);
}

/* One piece of an outfit, from its card: the photo as large as the dialog allows, then what can be
   done about it. */
.syc-piece-photo {
    display: block;
    width: 100%;
    max-height: 55vh;
    object-fit: contain;
    border-radius: 8px;
    margin-bottom: 0.75rem;
}

.syc-piece-actions {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin-top: 0.75rem;
}

/* The admin's sample-closet editor: a .syc-confirm, wider and scrolling, because it is a whole
   garment form rather than a question. Opened over the page so it is in view wherever the Edit
   button was. */
.syc-sample-editor {
    width: 760px;
    max-height: calc(100vh - 2rem);
    overflow-y: auto;
}

.syc-confirm-title {
    font-size: 1.05rem;
    font-weight: 600;
    margin: 0 0 0.4rem;
    color: var(--syc-text);
}

.syc-confirm-body {
    font-size: 0.9rem;
    color: var(--syc-text-muted);
    margin: 0 0 1rem;
}

.syc-confirm-actions {
    display: flex;
    justify-content: flex-end;
    gap: 0.5rem;
}

/* The dimmed ground behind a dialog. Its own rule again: the original went out with the add sheet
   it was written for, and the delete confirmation needs the same thing.

   -- What sits above what -----------------------------------------------------
   Written down because getting it wrong has now produced the same bug three times, each time as
   something that had simply disappeared:

     1020  the closet's sticky controls row
     1030  the trip's docked drawer      -- makes a stacking context; see TripPacking
     1035  the tab bar
     1040  the screen's own bar          -- makes a stacking context; the More drawer is inside it
     1090  the photo-reading overlay
     1199  the clothes-picker scrim
     1200  the clothes picker
     1210  this, the dimmed ground for a dialog
     1211  the dialogs themselves        -- .syc-look, .syc-confirm
     1220  the crop tool                 -- opened from inside a dialog, so above them

   A dialog has to clear the picker because it opens from inside it: tapping a garment in the sheet
   opens the larger photograph. At 1091, against a sheet that had just been raised to 1200, that
   photograph opened underneath the closet -- reported as "I tapped on the garment to open it
   bigger. I did not see it. I closed the closet and the garment was UNDER it."

   This ground and the dialogs it is for move together or not at all. They were 1091 and 1092;
   raising one without the other puts a dialog behind its own shade, which is the bug the note on
   .syc-look already describes from the time before. */
.syc-sheet-backdrop {
    position: fixed;
    inset: 0;
    z-index: 1210;
    background: rgba(0, 0, 0, 0.45);
}

/* The item screen's header: nothing on the left, the stepping arrows dead centre, Back on the
   right where every other screen puts it. Centred absolutely rather than by flex, because with
   only two children flex would centre the arrows in what is left over rather than in the header. */
.syc-item-header {
    position: relative;
    justify-content: flex-end;
}

.syc-item-header .syc-item-header-steps {
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

/* ── The closet's control row ──────────────────────────────────────────────────
   One row holding everything that changes what the grid shows: the view, the filters, and the
   select mode. It was three stacked rows, and once you had scrolled a hundred garments they were
   all a long way up.

   Sticky rather than a "back to top" button: that would be one more permanent control that earns
   its keep only when you are lost, and this costs no button and no tap. */
.syc-closet-controls {
    position: sticky;
    /* Under the header, not at the top of the window. Both headers are sticky themselves, so a row
       at top:0 slides underneath one and is half hidden by it. The height is measured at runtime
       rather than written down here: it differs between the two hosts and changes again with the
       phone's safe area, and a number typed here would be wrong on something. See nav.js. */
    top: var(--syc-sticky-top, 0px);
    z-index: 1020;
    display: flex;
    align-items: center;
    gap: 0.4rem;
    /* Sideways rather than wrapping, so it stays one line however many filters there are. */
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    padding: 0.5rem 0;
    margin-bottom: 0.75rem;
    /* Opaque, or the grid scrolls through it. */
    background: var(--syc-bg, #fff);
    border-bottom: 1px solid var(--syc-border);
}

.syc-closet-controls::-webkit-scrollbar { display: none; }

.syc-closet-controls > * { flex: 0 0 auto; }

/* Against the right edge rather than the left.

   Everything on this row is a control, and the grid below it is the content; a control row that
   starts at the left margin reads as the first line of that content. Pushed right, it reads as the
   toolbar it is, and lands under the thumb rather than across the screen from it.

   Done by pushing the first child rather than with justify-content: flex-end, which is the obvious
   way and breaks scrolling. This row overflows sideways on purpose, and a flex-end row that
   overflows puts its first items off the left edge where they cannot be scrolled back to. */
.syc-closet-controls > :first-child { margin-inline-start: auto; }

/* Separates the view from the filters, and the filters from the mode: three kinds of thing on one
   row need to read as three groups rather than one long list. */
.syc-controls-divider {
    width: 1px;
    align-self: stretch;
    margin: 0.15rem 0.25rem;
    background: var(--syc-border);
}

/* Filtering by colour -- see ColourChips.

   It has lived on its own row under the controls and inside the clothes picker, and had no rules
   of its own in either place: a bare label around a Bootstrap select, which is a block that fills
   its line. On the control row that made it as wide as the screen. */
.syc-colour-filter { display: inline-flex; align-items: center; }

/* The dates, standing in for the calendar that chose them.

   A whole-width control rather than a line of text: it is a button, and a button that looks like a
   sentence is a sentence people do not tap. Shaped like the form's other fields, because it stands
   where one of them would. */
.syc-date-summary {
    width: 100%;
    display: flex;
    align-items: center;
    gap: .6rem;

    padding: .55rem .75rem;
    border: 1px solid var(--syc-border);
    border-radius: var(--syc-radius, 6px);
    background: var(--syc-surface);
    color: var(--syc-text);
    font-size: .95rem;
    text-align: start;
}

.syc-date-summary > span:first-of-type { flex: 1 1 auto; min-width: 0; }

.syc-date-summary i { color: var(--syc-accent-dark); }

/* The word that says it can be tapped. The dates read as a value, and a value in a box is a thing
   people assume they have to go somewhere else to change. */
.syc-date-summary-change {
    flex: 0 0 auto;
    font-size: .85rem;
    font-weight: 600;
    color: var(--syc-accent-dark);
}

/* ── Guidance ─────────────────────────────────────────────────────────────────
   The prep list on an empty closet. Quiet: it is advice, offered once, next to the button that
   actually starts the work. */
.syc-prep {
    margin: 1.25rem auto 0;
    max-width: 26rem;
    text-align: left;
    padding: 0.9rem 1rem;
    border: 1px solid var(--syc-border);
    border-radius: var(--syc-radius);
    background: var(--syc-surface-alt);
}

.syc-prep-title {
    font-weight: 600;
    font-size: 0.9rem;
    margin: 0 0 0.5rem;
    color: var(--syc-text);
}

.syc-prep-list {
    margin: 0 0 0.6rem;
    padding-left: 1.1rem;
    font-size: 0.85rem;
    color: var(--syc-text-muted);
}

.syc-prep-list li { margin-bottom: 0.3rem; }

.syc-prep-link { font-size: 0.85rem; font-weight: 600; }

/* The single line on the add screen. Deliberately small: seen on every batch. */
.syc-add-guidance {
    margin: 0.9rem 0 0;
    font-size: 0.85rem;
}

/* Headings inside the guide. */
.syc-guide-heading {
    font-size: 1rem;
    font-weight: 600;
    color: var(--syc-text);
    margin: 0 0 0.5rem;
}

/* ── One duplicate photo, full size ───────────────────────────────────────────
   Two pairs of jeans at thumbnail size are two dark rectangles. The wash, the stitching and the
   hem are what tell them apart, and none of it survives at 160px. */
.syc-lightbox {
    position: fixed;
    inset: 0;
    z-index: 1100;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.75rem;
    padding: 1.5rem;
    /* Nearly black, so the garment is the only thing to look at. */
    background: rgba(0, 0, 0, 0.92);
    cursor: zoom-out;
}

.syc-lightbox img {
    max-width: 100%;
    max-height: 78vh;
    object-fit: contain;
}

.syc-lightbox-name {
    margin: 0;
    color: #fff;
    font-size: 0.9rem;
    text-align: center;
}

/* A visible way out as well as tapping the backdrop -- tap-anywhere is easy to miss, and this is
   modal. */
.syc-lightbox-close {
    position: absolute;
    top: calc(1rem + env(safe-area-inset-top, 0px));
    right: 1rem;
}

/* Separates a chip's label from its count: "All items 81" reads as a garment called 81. */
.syc-chip-dash {
    margin: 0 0.35rem;
    color: var(--syc-text-muted);
}

/* A count beside an admin tab or section heading: how much is behind it, without opening it. */
.syc-admin-count {
    display: inline-block;
    margin-left: 0.35rem;
    padding: 0.05rem 0.4rem;
    border-radius: 999px;
    background: var(--syc-surface-alt);
    color: var(--syc-text-muted);
    font-size: 0.75rem;
    font-weight: 600;
}

/* The dashboard's sections are disclosures now, closed to start with: six cards open at once is a
   wall, and the answer is usually in one of them. */
.syc-admin-section > summary {
    cursor: pointer;
    list-style: none;
}

.syc-admin-section > summary::-webkit-details-marker { display: none; }

.syc-admin-section > summary::before {
    content: "\F285";
    font-family: "bootstrap-icons";
    font-size: 0.8rem;
    margin-right: 0.5rem;
    display: inline-block;
    transition: transform var(--syc-transition);
}

.syc-admin-section[open] > summary::before { transform: rotate(90deg); }

/* Subtypes nested inside their garment type. Indented and quieter than the type above them, so
   the two levels read as an outline rather than as two competing headings. */
.syc-subtype-group {
    margin: 0 0 0.5rem 0.75rem;
    border-left: 2px solid var(--syc-border);
    padding-left: 0.75rem;
}

.syc-subtype-summary {
    cursor: pointer;
    list-style: none;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.35rem 0;
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--syc-text-muted);
}

.syc-subtype-summary::-webkit-details-marker { display: none; }

.syc-subtype-summary::before {
    content: "\F285";
    font-family: "bootstrap-icons";
    font-size: 0.7rem;
    transition: transform var(--syc-transition);
}

.syc-subtype-group[open] > .syc-subtype-summary::before { transform: rotate(90deg); }

/* A piece of a suggestion, when tapping it opens the garment. The lift is small: these sit in rows
   of three or four, and anything stronger would make a suggestion look like a set of buttons. */
.syc-outfit-piece-tappable {
    cursor: pointer;
    border-radius: var(--syc-radius);
    transition: transform var(--syc-transition);
}

.syc-outfit-piece-tappable:hover,
.syc-outfit-piece-tappable:focus-visible {
    transform: translateY(-2px);
}

.syc-outfit-piece-tappable:focus-visible {
    outline: 2px solid var(--syc-accent);
    outline-offset: 2px;
}

/* "Built around this garment" — says why the ideas below are narrow, and how to widen them.
   Its own row above the filters rather than among them: it is not a filter, it is the subject. */
.syc-around-banner {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
    margin-bottom: .75rem;
    padding: .5rem .75rem;
    border: 1px solid var(--syc-border, #E1DED6);
    border-left: 3px solid var(--syc-accent, #EE5A3C);
    border-radius: .5rem;
    background: var(--syc-surface-muted, #F6F5F1);
    font-size: .9rem;
}

/* "Past your recommended set" — a state rather than a score. Green instead of the accent pill,
   because it is saying something is complete rather than reporting a measurement. */
.syc-glance-covered {
    color: var(--syc-success-dark, #1e6b41);
    background: var(--syc-success-subtle, #e3f3e9);
}

/* Rows in the glance cards and neglect list that open the garment behind them. */
a.syc-glance-link,
a.syc-glance-link:hover {
    text-decoration: none;
    color: inherit;
}
a.syc-glance-link:hover { background: var(--syc-accent-subtle); }

/* Logging a wearing, on the garment's own screen. Sits under the actions rather than among them:
   recording what you wore is a different kind of act from editing what it is. */
.syc-wear-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem .75rem;
    margin-top: .75rem;
    padding-top: .75rem;
    border-top: 1px solid var(--syc-border);
}
.syc-wear-done { color: var(--syc-success-dark, #1e6b41); font-weight: 600; font-size: .9rem; }
.syc-wear-undo { padding: 0; font-size: .85rem; }
.syc-wear-count { color: var(--syc-text-muted); font-size: .85rem; margin-left: auto; }

/* A garment the app is asking about: photograph beside the reasons, never above them. The reason
   is what makes the question a question rather than a verdict, so it reads at the same level as
   the name rather than as a caption. */
.syc-candidate { display: flex; gap: .9rem; align-items: flex-start; }
.syc-candidate-photo { flex: 0 0 88px; display: block; }
.syc-candidate-photo img,
.syc-candidate-photo .syc-outfit-noimg {
    width: 88px;
    aspect-ratio: 3 / 4;
    object-fit: contain;
    border-radius: var(--syc-radius);
    border: 1px solid var(--syc-border);
    background-color: var(--syc-surface-alt);
    display: block;
}
.syc-candidate-body { flex: 1 1 auto; min-width: 0; }
.syc-candidate-name { font-weight: 600; margin-bottom: .35rem; }
.syc-candidate-reasons {
    margin: 0 0 .7rem;
    padding-left: 1.1rem;
    font-size: .875rem;
    color: var(--syc-text-muted);
}
.syc-candidate-reasons li { margin-bottom: .15rem; }
.syc-candidate-actions { display: flex; flex-wrap: wrap; gap: .5rem; }

/* The two questions on a shortlist card. Below the reasons and above the decisions, because that
   is the order somebody works in: why is this here, what do I know about it, what now. */
.syc-candidate-asks { display: flex; flex-direction: column; gap: .55rem; margin-bottom: .7rem; }
.syc-candidate-ask-label {
    display: block;
    font-size: .78rem;
    color: var(--syc-text-muted);
    margin-bottom: .2rem;
}

/* Reading a garment, the photograph shares the screen with what is being read. Editing it, the
   picture is the thing being worked on and gets its height back. */
/* Narrower, not shorter. The carousel is aspect-ratio 1/1, so its height comes from its width and
   a max-height was simply ignored -- which is why the picture looked unchanged. Eighty per cent of
   the width takes the same off the height, and centring keeps it where the eye already was. */
.syc-photos-compact .syc-carousel {
    max-width: 80%;
    margin-left: auto;
    margin-right: auto;
}

/* Add photos and the count on one row, under the picture rather than over it. */
.syc-gallery-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .75rem;
}
.syc-gallery-footer .syc-gallery-count { margin-left: auto; font-size: .8rem; color: var(--syc-text-muted); }

/* The garment's wear history, with deleting at the far end of the same row -- present, and not
   where a thumb lands by accident. */
.syc-wear-count-lead { font-size: .9rem; color: var(--syc-text); }
.syc-wear-row .syc-wear-undo { margin-left: auto; }

/* Choosing when something was worn. Two answers people actually give, then a date for the rest.
   The dialog itself is .syc-confirm, which already exists -- a second one would only be the same
   thing spelled differently. */
.syc-sheet-choices { display: flex; gap: .5rem; }
.syc-sheet-choices .btn { flex: 1 1 0; }

/* One garment in the wear history: photograph, name, and the days underneath. A row rather than a
   card, because the list is read down and cards would put a frame round every line of it. */
.syc-worn-row {
    display: flex;
    gap: .7rem;
    align-items: flex-start;
    padding: .55rem 0;
    border-bottom: 1px solid var(--syc-border);
    text-decoration: none;
    color: inherit;
}
.syc-worn-row:last-child { border-bottom: none; }
.syc-worn-row:hover { background: var(--syc-accent-subtle); }
.syc-worn-thumb {
    flex: 0 0 44px;
    width: 44px;
    aspect-ratio: 3 / 4;
    object-fit: contain;
    border-radius: var(--syc-radius);
    border: 1px solid var(--syc-border);
    background-color: var(--syc-surface-alt);
}
.syc-worn-body { display: flex; flex-direction: column; min-width: 0; }
.syc-worn-name { font-size: .9rem; font-weight: 500; }
.syc-worn-dates { font-size: .78rem; color: var(--syc-text-muted); line-height: 1.45; }

/* Sort sits at the far end of the controls row, where a setting belongs rather than in the run of
   filters. Static "All items" beside it is a count, not a button — it stopped being a choice when
   grouping became one of the orders. */
/* The two questions anybody asks of a closet -- what order, and what colour -- as two menus of the
   same size beside each other. They shared a row only once the count moved out of it and the
   longest sort option lost two words ("Recently added" -> "Recents"): a select is as wide as its
   widest option, so that word was setting the width of the control. */
.syc-sort .form-select,
.syc-colour-filter .form-select { width: auto; min-width: 7rem; max-width: 9rem; }
.syc-chip-static { cursor: default; background: transparent; }

/* ------------------------------------------------------------------ packing lists

   Two lists on one page, and they are drawn differently on purpose. Garments came out of the
   closet and have photographs, so they are a grid of pictures. Essentials were never photographed
   and never will be, so they are lines with a number. Drawing both the same way would either put
   an empty grey rectangle where a toothbrush is, or hide the garments the app chose. */

.syc-trip-garments {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(6.5rem, 1fr));
    gap: .85rem;
}

.syc-trip-garment { display: flex; flex-direction: column; align-items: center; gap: .2rem; }

/* The photograph is the tick. There is no room beside a thumbnail this size for a checkbox, and
   tapping the picture of the thing you just put in the case is what anybody would try first. */
.syc-trip-photo {
    position: relative;
    display: block;
    width: 100%;
    padding: 0;
    border: 1px solid var(--syc-border);
    border-radius: var(--syc-radius);
    background: var(--syc-surface-alt);
    overflow: hidden;
    cursor: pointer;
}
.syc-trip-photo img { width: 100%; aspect-ratio: 3 / 4; object-fit: contain; display: block; }
.syc-trip-photo:focus-visible { outline: 2px solid var(--syc-accent); outline-offset: 2px; }

/* Packed reads as done rather than as gone: dimmed and ticked, still legible. A packed garment
   that vanished would leave somebody unable to check what they had already done. */
.syc-trip-garment.packed .syc-trip-photo { opacity: .45; }
.syc-trip-garment.packed .syc-trip-garment-name { text-decoration: line-through; }

.syc-trip-garment-name {
    font-size: .78rem;
    line-height: 1.3;
    text-align: center;
    color: var(--syc-text-muted);
}

.syc-trip-group { margin-bottom: 1rem; }
.syc-trip-group-name {
    font-size: .72rem;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--syc-text-muted);
    margin-bottom: .3rem;
}

.syc-trip-line {
    display: flex;
    align-items: center;
    gap: .6rem;
    padding: .45rem 0;
    border-bottom: 1px solid var(--syc-border-subtle, var(--syc-border));
}
.syc-trip-line:last-child { border-bottom: none; }
/* Replaced by the child-scoped rule below, which leaves the thumbnail alone. */

/* Still being decided, and it should look it.

   No tick on these lines, because the tick asks whether the thing is in the suitcase yet and a
   maybe has no answer to that. Indented to where the ticked lines' text starts, so the column
   still reads straight down without a checkbox holding the place open. */
.syc-trip-line.undecided { color: var(--syc-text-muted); padding-left: 1.75rem; }

/* The garment on a checklist line.

   Sized for a list rather than for a grid. The point of a packing list is running down it with a
   case open, and thumbnails at the size the choosing screens use would turn twenty garments into
   six screens of scrolling -- so this is just big enough to tell the cream trousers from the white
   ones, and it opens the full photograph when it is not. Contained, like every other garment
   photograph in the app: a square crop takes the hem off a dress, which is most of what
   distinguishes it. */
.syc-trip-thumb {
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    width: 2.5rem;
    height: 2.5rem;
    padding: 0;
    border: 1px solid var(--syc-border);
    border-radius: var(--syc-radius);
    background: var(--syc-surface-alt);
    overflow: hidden;
    cursor: pointer;
}

.syc-trip-thumb img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    display: block;
}

.syc-trip-thumb .syc-outfit-noimg { color: var(--syc-text-muted); font-size: .9rem; }

.syc-trip-thumb:focus-visible { outline: 2px solid var(--syc-accent); outline-offset: 2px; }

/* The line-through belongs to the name, not to the caption under a photograph. Scoped so the
   thumbnail is not struck through with it. */
.syc-trip-line.packed > span { text-decoration: line-through; color: var(--syc-text-muted); }

/* The number is the button: changing how many is the only thing anybody wants to do to one of
   these lines, so it does not need a control of its own next to it. */
.syc-trip-qty-btn {
    min-width: 1.9rem;
    padding: 0 .35rem;
    border: 1px solid var(--syc-border);
    border-radius: var(--syc-radius);
    background: var(--syc-surface-alt);
    font-size: .82rem;
    font-variant-numeric: tabular-nums;
    color: var(--syc-text);
    cursor: pointer;
}
.syc-trip-qty-btn:focus-visible { outline: 2px solid var(--syc-accent); outline-offset: 1px; }
.syc-trip-qty { width: 4rem; }

/* The way in to trips, at the top of Outfits. A link that looks like a card, so it reads as a
   place to go rather than as one more saved outfit. */

/* ── What the case makes (TripPacking, "Show what this makes") ─────────────────
   A row per outfit: the pieces side by side, then their names. Rows rather than the grid the
   garments use, because the unit here is the pairing and a grid would show the same six garments
   twelve times with nothing saying which two go together. */
.syc-trip-outfit {
    display: flex;
    align-items: center;
    gap: .5rem;
    padding: .5rem 0;
    border-block-end: 1px solid var(--syc-border);
}

.syc-trip-outfit:last-of-type {
    border-block-end: none;
}

.syc-trip-outfit-piece {
    flex: 0 0 auto;
    width: 3rem;
    height: 3rem;
    border: 1px solid var(--syc-border);
    border-radius: var(--syc-radius);
    background: var(--syc-surface-alt);
    overflow: hidden;
}

.syc-trip-outfit-piece img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.syc-trip-outfit-names {
    flex: 1 1 auto;
    min-width: 0;
    font-size: .85rem;
    color: var(--syc-text-muted);
}

/* The two ways of filling a case, side by side and the same size. Sized by their flex basis rather
   than their labels: "Fill in around my picks" is three times the length of "Add your own", and
   letting the text decide made one read as the action and the other as an afterthought. */
.syc-trip-actions > .btn {
    flex: 1 1 0;
    min-width: 0;
}

/* The grid on its way back to the card you came from.
   Hidden rather than removed: the cards have to be in the page for there to be anything to scroll
   to, and without this the eye gets the top of the closet first and the right place second. */
.syc-restoring {
    visibility: hidden;
}

/* How many nights of each thing, under the occasion chips (TripPlanForm). Rows rather than a grid:
   the unit is one occasion and its number, and they read left to right like a sentence. */
.syc-trip-nights {
    display: flex;
    flex-direction: column;
    gap: .35rem;
}

.syc-trip-night-row {
    display: flex;
    align-items: center;
    gap: .5rem;
}

/* The itinerary (TripPacking, "Your nights"). One block per night: its label, then what is on it.
   Separated by a rule rather than cards, because these are a sequence and cards would make four
   nights look like four unrelated things. */
.syc-trip-night {
    padding: .6rem 0;
    border-block-end: 1px solid var(--syc-border);
}

.syc-trip-night:last-of-type {
    border-block-end: none;
}

.syc-trip-night-label {
    display: flex;
    align-items: baseline;
    gap: .5rem;
    margin-block-end: .35rem;
}

.syc-trip-night-number {
    font-weight: 600;
}

/* The occasion is what distinguishes one night from another, so it reads before the garments. */
.syc-trip-night-occasion {
    font-size: .8rem;
    padding: .1rem .5rem;
    border-radius: 999px;
    background: var(--syc-accent-subtle);
    color: var(--syc-primary);
}

/* ── The itinerary (TripPacking, "Your trip") ──────────────────────────────────
   A day is a group of changes, so it reads as one block with its changes indented under it. */
.syc-trip-day { margin-block-end: 1.25rem; }

.syc-trip-day-name {
    font-family: inherit;
    font-weight: 700;
    font-size: 1.05rem;
    padding-block-end: .3rem;
    border-block-end: 2px solid var(--syc-border);
    margin-block-end: .5rem;
}

.syc-trip-slot {
    padding: .5rem 0 .6rem;
    border-block-end: 1px solid var(--syc-border);
}

.syc-trip-slot:last-of-type { border-block-end: none; }

.syc-trip-slot-head {
    display: flex;
    align-items: center;
    gap: .5rem;
    margin-block-end: .4rem;
}

.syc-trip-slot-name { font-weight: 600; }

/* Three across with the name underneath -- the same shape as the closet grid, so a garment looks
   the same wherever you meet it. Two on a phone; see the narrow-screen rule further down. */
.syc-slot-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: .5rem;
}

.syc-slot-piece { display: flex; flex-direction: column; gap: .2rem; min-width: 0; }

/* Contained, not cropped.

   A square crop of a garment photographed upright cuts the hem off a dress and both ends off a
   pair of trousers, which is most of what tells two pairs apart. It also made the enlarged view
   look like a different photograph: the crop was keeping the bright middle and the full frame
   shows the dark surround it was hiding. Letterboxing costs some pixels and shows the garment. */
.syc-slot-piece img,
.syc-slot-piece .syc-outfit-noimg {
    width: 100%;
    aspect-ratio: 1;
    object-fit: contain;
    border: 1px solid var(--syc-border);
    border-radius: var(--syc-radius);
    background: var(--syc-surface-alt);
}

.syc-slot-piece-name {
    font-size: .78rem;
    line-height: 1.25;
    color: var(--syc-text-muted);
    overflow-wrap: anywhere;
}

/* Pulled out, not decided on. Dashed rather than dimmed: dimming reads as unavailable, and these
   are the most available things on the screen -- the whole point of the pile is that you are about
   to choose from it. */
.syc-slot-piece.undecided img,
.syc-slot-piece.undecided .syc-outfit-noimg {
    border-style: dashed;
    border-color: var(--syc-accent);
}

/* Already in the case: the difference between finishing an outfit and enlarging the suitcase. */
.syc-slot-packed {
    display: inline-block;
    font-size: .68rem;
    padding: 0 .3rem;
    margin-inline-start: .2rem;
    border-radius: 999px;
    background: var(--syc-accent-subtle);
    color: var(--syc-primary);
}

.syc-slot-options {
    margin-block-start: .5rem;
    padding: .6rem;
    background: var(--syc-surface-alt);
    border-radius: var(--syc-radius);
}

.syc-slot-option-group { margin-block-end: .6rem; }

/* What goes underneath, on the day it is needed rather than summed in a list. */
.syc-trip-underneath {
    margin-block: .45rem 0;
    font-size: .8rem;
    color: var(--syc-text-muted);
}

/* ── The packing wizard (TripPacking) ──────────────────────────────────────────
   One day per screen, so the page holds one decision rather than the whole trip. */
.syc-trip-summary {
    display: flex;
    align-items: baseline;
    gap: .5rem;
    margin-block-end: .5rem;
}

.syc-step-title {
    font-size: 1.15rem;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    padding-block-end: .3rem;
    border-block-end: 2px solid var(--syc-border);
    margin-block-end: .75rem;
}

.syc-slot { margin-block-end: 1.25rem; }

/* A slot heading is a summary, and had nothing on it that said so.

   Setting display:flex on a <summary> removes the browser's disclosure triangle, so Day and
   Evening were two words with no affordance at all -- and the widest control in the open slot was
   the dressiness select, which is what got tapped instead when somebody wanted to close it. The
   chevron goes on the right, where the day headings above it are not, because this is the row the
   thumb is already near. */
.syc-slot-head {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: .4rem;
    padding: .5rem .1rem;
    margin-block-end: .5rem;
    border-block-end: 1px solid var(--syc-border);
    list-style: none;
    cursor: pointer;
}

.syc-slot-head::-webkit-details-marker { display: none; }

.syc-slot-head > .syc-type-count { margin-inline-start: auto; }

/* A target, not a dot.

   It went on at the default glyph size, which on a phone is a speck at the end of a row -- the
   whole summary opens the slot, but nothing looked like the thing to press. Given a round face
   and a thumb's worth of size it reads as the control it has been all along. */
.syc-slot-head::after {
    content: "▾";
    display: grid;
    place-items: center;
    flex: 0 0 auto;
    width: 2.25rem;
    height: 2.25rem;
    margin-inline-start: .1rem;
    border: 1px solid var(--syc-border);
    border-radius: 999px;
    background: var(--syc-surface);
    color: var(--syc-text);
    font-size: 1.15rem;
    line-height: 1;
    transition: transform .15s ease;
}

.syc-slot[open] > .syc-slot-head::after { transform: rotate(180deg); }

.syc-slot-title { font-weight: 600; }

/* Where you are and how to move. Above the tab bar on a phone, since that is where the thumb
   already is and the alternative is scrolling back for it on every day. */
.syc-step-nav {
    position: sticky;
    inset-block-end: calc(env(safe-area-inset-bottom, 0px) + .5rem);
    display: flex;
    align-items: center;
    gap: .75rem;
    padding: .5rem .75rem;
    margin-block-start: 1rem;
    background: var(--syc-surface);
    border: 1px solid var(--syc-border);
    border-radius: var(--syc-radius);
    box-shadow: 0 2px 10px rgba(0, 0, 0, .08);
}

.syc-step-count {
    flex: 1 1 auto;
    text-align: center;
    font-size: .85rem;
    color: var(--syc-text-muted);
    font-variant-numeric: tabular-nums;
}

/* The thumbnail is the control: tapping the picture of a garment is what anybody tries first, and
   there is no room beside one this size for a checkbox. */
.syc-slot-photo {
    position: relative;
    display: block;
    width: 100%;
    padding: 0;
    border: 1px solid var(--syc-border);
    border-radius: var(--syc-radius);
    background: var(--syc-surface-alt);
    overflow: hidden;
    cursor: pointer;
}

.syc-slot-photo img,
.syc-slot-photo .syc-outfit-noimg {
    width: 100%;
    aspect-ratio: 1;
    object-fit: contain;
    display: block;
}

.syc-slot-photo.chosen {
    border-color: var(--syc-accent-dark);
    box-shadow: 0 0 0 2px var(--syc-accent);
}

/* Names are dropped where the screen is narrow -- a phone shows three thumbnails a row and the
   name under each costs a line of height on every garment in the closet. Roomier screens keep
   them, where the space is there and reading is faster than recognising. */
/* A phone is not a narrower desktop, and this grid is where that shows.

   Reported from testing on the phone: the garments are hard to see. Three thumbnails across a
   430px screen is about 130px each, and at that size -- as a note further up this file already
   admits -- "a white trouser and a cream one are the same small rectangle". The name underneath
   was the thing that would have told them apart, and it was switched off here for want of room,
   so the two failures were each other's cause.

   Two across gives roughly half again the width and enough room to put the name back. The desktop
   stays at three: there the thumbnails are large enough to tell apart, and two would be a wall of
   photographs with four garments on a screen. */
@media (max-width: 575.98px) {
    .syc-slot-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* What a change of clothes is for, and how dressy. The label is for the reader; the level is what
   the picker aims at. Side by side because they are one answer to one question. */
.syc-slot-plan {
    display: flex;
    flex-wrap: wrap;
    gap: .4rem;
    margin-block-end: .6rem;
}

.syc-slot-label { flex: 1 1 8rem; min-width: 0; }
/* Sized to its content and sitting beside the buttons, rather than a full-width row of its own.

   It was a whole line on every change of clothes, for a question answered once on the planner and
   rarely revisited -- and with a day now showing two slots in full, that is two lines of dropdown
   before any clothes appear. Reported as the screen being crowded and confusing.

   Still a native select, still one tap: this makes it smaller, not harder to reach. */
.syc-slot-level {
    flex: 0 1 auto;
    width: auto;
    max-width: 100%;
    min-width: 0;
}

/* Between the case and the rest of the wardrobe. Two lists of thumbnails with only a category name
   between them read as one list, and the difference between them is the whole point. */
.syc-closet-heading {
    margin-block: .9rem .35rem;
    font-weight: 600;
    font-size: .9rem;
    color: var(--syc-text-muted);
}

/* One day that is not ordinary, on the planner. Its name on one line and when-and-how-dressy on
   the next, because the name is the part somebody types and the rest is three quick choices. */
.syc-special {
    display: flex;
    flex-direction: column;
    gap: .3rem;
    padding: .5rem;
    margin-block-end: .5rem;
    border: 1px solid var(--syc-border);
    border-radius: var(--syc-radius);
}

/* The name and the way to remove it share a line; each choice gets its own.

   Three selects in a row on a phone is three abbreviations -- "Sat 26 S", "Dayti", "Smart c" --
   and no way to tell from the text which control is which. */
.syc-special-head {
    display: flex;
    align-items: center;
    gap: .4rem;
}

.syc-special-head > .form-control { flex: 1 1 auto; min-width: 0; }

.syc-special-field {
    display: flex;
    align-items: center;
    gap: .5rem;
}

.syc-special-field > span {
    flex: 0 0 5.5rem;
    font-size: .78rem;
    color: var(--syc-text-muted);
}

.syc-special-field > select { flex: 1 1 0; min-width: 0; }

/* An event's one change of clothes, titled rather than filed.

   A trip's slots are summaries inside a disclosure; an event has a heading and no drawer, so the
   styling that came free from <summary> has to be said here. Sized between the trip line above it
   and the garments below, because on an event screen this is the only heading there is. */
.syc-slot-heading {
    display: flex;
    align-items: center;
    gap: .5rem;
    flex-wrap: wrap;
    margin: 0 0 .75rem;
    padding-block-end: .5rem;
    border-block-end: 2px solid var(--syc-accent-light);
    font-size: 1rem;
}

/* No disclosure, so no chevron and no indent that was making room for one. */
.syc-slot-event { padding-inline-start: 0; }

/* A day is the strongest thing on the page: it is what you are looking for when you open this.

   Bold and a size up was not enough, and it could not be. Everything on this screen is grey text
   on a white card, so weight and size are the only two dials available and both of them were
   already turned up -- a day heading sat in the same colour as the muted note under it and the
   same ground as the rows below it. Reported as not standing out.

   So it gets the one thing nothing else here has: a ground of its own, in the accent rather than
   in grey. The colour is what the eye finds when scrolling for Friday; the weight is what it
   reads once it has stopped. */
/* The day accordion's styling lived here. A day is a step now -- see .syc-day-step -- so there is
   no summary to dress and no chevron to turn. The sticky trick it needed (overflow: clip, so the
   group did not become a scroll container and swallow the heading) went with it, and so did the
   sticky heading itself: with one day on screen there is nothing above it to scroll past. */

/* Day and Evening under it read as its parts rather than as two more rows. */
.syc-slot-title {
    font-weight: 700;
    font-size: .95rem;
    text-transform: uppercase;
    letter-spacing: .04em;
}

/* What the day is for, from the planner. Read here, typed there. */
.syc-slot-label-line {
    margin-block: 0 .35rem;
    font-weight: 600;
}

.syc-closet-link { margin-block-start: .4rem; }

/* What the closet is being narrowed by, and the way out of it. Said out loud because a list that
   has quietly hidden what you were looking for is worse than a long one. */

/* A closer look. At three thumbnails to a row a white trouser and a cream one are the same
   rectangle, and telling them apart is the whole job. */
.syc-slot-piece { position: relative; }

/* The tick is the control; the photograph is the photograph.

   It was the other way round -- tapping a garment put it on the day -- and the two things somebody
   does most here are choosing and looking, with looking by far the more frequent: you tap a
   thumbnail to find out what it is, and finding out cost you a garment you then had to undo. So
   the tap enlarges, and adding is the tick.

   Always drawn, not only when on. A control that appears once the thing is done is a control
   nobody can find beforehand, which is what the old X in the corner was. */
.syc-slot-pick {
    position: absolute;
    inset-block-start: .25rem;
    inset-inline-end: .25rem;
    z-index: 2;
    display: grid;
    place-items: center;
    width: 1.75rem;
    height: 1.75rem;
    padding: 0;
    border: 1px solid var(--syc-border);
    border-radius: 999px;
    background: var(--syc-surface);
    color: var(--syc-text-muted);
    font-size: .8rem;
    box-shadow: 0 1px 3px rgba(0, 0, 0, .18);
    cursor: pointer;
    transition: background .12s ease, color .12s ease, border-color .12s ease;
}

/* Taking a garment off the day it is on.

   The same round corner button as the picker's tick, and deliberately not the same colour. In the
   picker a filled pink circle means "this one is coming"; here every garment in the grid is
   already on the day, so a filled pink circle meant nothing at all and read as four checkboxes
   nobody could explain. This one is quiet until it is wanted, which is what a remove should be. */
.syc-slot-drop {
    background: var(--syc-surface);
    border-color: var(--syc-border);
    color: var(--syc-text-muted);
}

.syc-slot-pick.on {
    background: var(--syc-accent);
    border-color: var(--syc-accent-dark);
    color: var(--syc-on-accent, #14262B);
}

.syc-slot-pick:focus-visible { outline: 2px solid var(--syc-accent); outline-offset: 2px; }

/* Above its own shade, and above the closet it opens from.

   Twice wrong. First it sat at 1060 under a backdrop of 1091, so the enlarged photograph was
   painted under a sheet of 45% black and read as a darker copy of the thumbnail -- the one
   explanation nobody would arrive at, since the two are the same file. Then the clothes picker was
   raised to 1200 and this went under the picker itself, which is worse: the photograph opened
   behind the closet, with nothing on screen to say it had opened at all.

   See the ladder on .syc-sheet-backdrop. This and that move together. */
.syc-look {
    position: fixed;
    inset-block-start: 50%;
    inset-inline-start: 50%;
    transform: translate(-50%, -50%);
    z-index: 1211;
    width: min(22rem, calc(100vw - 2rem));

    /* dvh, not vh. On a phone vh counts the strip behind the address bar, so a card sized to
       calc(100vh - 4rem) reaches an inch past what anyone can see -- and what it hid was the
       bottom, where the buttons are. The dynamic unit is the visible viewport. */
    max-height: calc(100dvh - 4rem);

    /* A column with a foot that does not move. It used to be one scrolling box, so a tall
       photograph pushed the name and both buttons out of sight and the dialog read as an error:
       no title, no Close, nothing to do. Now the picture is the part that gives. */
    display: flex;
    flex-direction: column;
    padding: 1rem;
    background: var(--syc-surface);
    border: 1px solid var(--syc-border);
    border-radius: var(--syc-radius);
    box-shadow: 0 8px 30px rgba(0, 0, 0, .25);
}

/* min-height:0 is the whole trick: without it a flex child refuses to shrink below the height of
   its content, which is exactly the tall photograph being shrunk. */
.syc-look-photo {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    display: flex;
    align-items: flex-start;
    justify-content: center;
}

.syc-look img {
    width: 100%;

    /* Contained rather than cropped, and capped, so a full-length dress is a whole dress. A crop
       here would repeat the mistake the thumbnails made: the hem and the shoulders are most of
       what tells two dresses apart. */
    max-height: 60dvh;
    object-fit: contain;
    border-radius: var(--syc-radius);
    display: block;
}

/* Always on screen, whatever the photograph is doing above it. */
.syc-look-foot { flex: 0 0 auto; }

.syc-look-name { font-weight: 600; margin-block: .6rem .8rem; }

/* Wrapping, now that there are four. Edit, Donate, Not coming and Close come to about 300px of
   the 320 a phone leaves inside this card, which fits and would stop fitting the moment any label
   grew or anybody's text was scaled up. A second row is fine; a squashed one is not. */
.syc-look-actions {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
    justify-content: flex-end;
}

/* A way out in the corner as well as in the row.

   The row was below the fold when this was reported, and a dialog whose only exit is a button
   nobody can see is a dialog people force-quit the app out of. Tapping the backdrop already
   closed it, which is invisible if you do not know it. */
.syc-look-close {
    position: absolute;
    inset-block-start: .4rem;
    inset-inline-end: .4rem;
    z-index: 1;
    display: grid;
    place-items: center;
    width: 2rem;
    height: 2rem;
    padding: 0;
    border: 1px solid var(--syc-border);
    border-radius: 999px;
    background: var(--syc-surface);
    color: var(--syc-text-muted);
    font-size: .8rem;
    cursor: pointer;
}

.syc-look-close:focus-visible { outline: 2px solid var(--syc-accent); outline-offset: 2px; }

/* The Fill button, now that the slot heading is a summary and cannot hold one. */
/* Everything you can do to this change of clothes, on one line: fill it, shuffle it, say how
   dressy it is. Three stacked rows became one. Wrapping rather than shrinking, so a long level
   name on a narrow phone drops to a second line instead of squeezing the buttons. */
.syc-slot-actions {
    margin-block: .4rem;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .4rem;
}

/* Where the clothes that are not in play have gone.

   A quiet line rather than a banner: this is a state somebody chose, not an errand waiting for
   them, and a coloured box repeating it on every visit would be nagging. */
.syc-stored-line {
    margin-block: 0 .75rem;
    font-size: .85rem;
    color: var(--syc-text-muted);
}

.syc-stored-line a { color: inherit; }

/* The closet's own size, first in that line. Not a link and not a pill: it is the one fact here
   with nowhere to go, and a border around it promised a tap that never did anything. */
.syc-stored-count { white-space: nowrap; }

.syc-stored-sep { margin-inline: .5rem; opacity: .5; }

/* Possible duplicates, in the same line as the counts but in Brick: an errand among states. */
.syc-stored-line a.syc-stored-errand { color: var(--syc-accent-dark); font-weight: 600; white-space: nowrap; }

/* What size a batch of photographs is.

   Above the rows rather than in them: it is one answer about forty garments, and a control
   repeated forty times would be the thing it exists to avoid. Boxed, because it applies to
   everything below it and an unboxed row of selects reads as belonging to the first garment. */
.syc-bulk-sizes {
    display: flex;
    flex-direction: column;
    gap: .5rem;
    margin-block-end: 1rem;
    padding: .75rem;
    border: 1px solid var(--syc-border);
    border-radius: var(--syc-radius);
    background: var(--syc-surface-alt);
}

.syc-bulk-sizes-title { font-weight: 600; font-size: .9rem; }

/* Label above control, not beside it. Side by side on a phone leaves about seven characters for
   "Tops and coats", and an abbreviation nobody can read is worse than a second line. */
.syc-bulk-size-field {
    display: flex;
    flex-direction: column;
    gap: .2rem;
    font-size: .8rem;
    color: var(--syc-text-muted);
}

/* ─── More: the drawer behind the hamburger ─────────────────────────────────────────────────── */

/* Full-bleed on a phone, a panel on anything wider. It holds a dozen links and nothing else, so
   there is no reason for it to be wide. */
.syc-more-drawer {
    position: fixed;
    inset-block: 0;
    inset-inline-start: 0;
    z-index: 1200;
    width: min(20rem, 86vw);
    display: flex;
    flex-direction: column;
    background: var(--syc-surface);
    border-inline-end: 1px solid var(--syc-border);
    box-shadow: 4px 0 24px rgba(0, 0, 0, .18);
    overflow-y: auto;

    /* Off-screen rather than absent, so it slides rather than appears. Hidden from the reader as
       well as the eye while it is out there -- a drawer nobody can see should not be tabbable. */
    transform: translateX(-100%);
    visibility: hidden;
    transition: transform .2s ease, visibility .2s;
}

.syc-more-drawer.open { transform: translateX(0); visibility: visible; }

.syc-more-backdrop {
    position: fixed;
    inset: 0;
    z-index: 1199;
    border: none;
    padding: 0;
    background: rgba(0, 0, 0, .45);
    cursor: pointer;
}

.syc-more-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 1rem;
    border-block-end: 1px solid var(--syc-border);
}

.syc-more-title {
    font-family: var(--syc-font-heading, inherit);
    font-size: 1.75rem;
    font-weight: 700;
    line-height: 1.1;
    color: var(--syc-primary);
}

.syc-more-close {
    display: grid;
    place-items: center;
    width: 2.25rem;
    height: 2.25rem;
    border: 1px solid var(--syc-border);
    border-radius: 999px;
    background: var(--syc-surface);
    color: var(--syc-text-muted);
    cursor: pointer;
}

.syc-more-links { display: flex; flex-direction: column; padding: .5rem 0; }

.syc-more-link {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .75rem;
    padding: .85rem 1rem;
    color: var(--syc-text);
    text-decoration: none;
    border-block-end: 1px solid var(--syc-border-subtle, var(--syc-border));
}

.syc-more-link:last-of-type { border-block-end: none; }
.syc-more-link:hover { background: var(--syc-surface-alt); }
.syc-more-link > span { display: flex; align-items: center; gap: .6rem; }
.syc-more-link .bi-chevron-right { color: var(--syc-text-muted); font-size: .8rem; }

/* A heading with its rows folded under it.

   Fifteen flat rows was too many to read, so the errands and the reference material sit inside
   three sections and only the three things somebody opens this drawer to do stay at the top.

   <details> rather than anything scripted, for the same reason the closet's type groups are: it
   needs no circuit behind it, which matters because this list is drawn inside a statically
   rendered header on the web as well as in the phone's drawer.

   The head deliberately matches .syc-more-link's metrics -- same padding, same icon gap -- so a
   heading and a row read as the same kind of thing at the same indent, one merely holding others. */
.syc-more-section {
    border-block-end: 1px solid var(--syc-border-subtle, var(--syc-border));
}

.syc-more-section:last-of-type { border-block-end: none; }

.syc-more-section-head {
    list-style: none;                 /* the default marker, replaced below with one that turns */
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .75rem;
    padding: .85rem 1rem;
    color: var(--syc-text);
    font-weight: 600;
}

.syc-more-section-head::-webkit-details-marker { display: none; }
.syc-more-section-head:hover { background: var(--syc-surface-alt); }
.syc-more-section-head > span { display: flex; align-items: center; gap: .6rem; }

/* The chevron, on the right where the rows keep theirs, turning to point down when the section is
   open.

   A real <i>, the same one every row in this drawer already carries, rather than a CSS glyph
   escape. The escape version is one backslash away from writing a control character into the
   stylesheet instead of a chevron -- which is exactly what it did, and nothing would have caught
   it, because a stylesheet is never compiled and no test renders this. */
.syc-more-section-head .bi-chevron-right {
    color: var(--syc-text-muted);
    font-size: .8rem;
    transition: transform .15s ease;
}

.syc-more-section[open] > .syc-more-section-head .bi-chevron-right { transform: rotate(90deg); }

/* Indented, and without their own dividers: inside a section the rows are a list under a heading
   rather than a second set of destinations. The last one keeps no border because the section
   already draws the line beneath itself. */
.syc-more-section .syc-more-link {
    padding-inline-start: 2.4rem;
    border-block-end: none;
}

.syc-more-section .syc-more-link:last-of-type { padding-block-end: 1rem; }

/* Apart from the rest, and quiet. It is the one thing here nobody means to tap. */
.syc-more-signout { margin-block-start: auto; padding: 1rem; }

.syc-more-signout-link {
    display: inline-flex;
    align-items: center;
    width: 100%;
    padding: .6rem .9rem;
    border: 1px solid var(--syc-border);
    border-radius: var(--syc-radius);
    background: var(--syc-surface);
    color: var(--syc-text-muted);
    font-size: .9rem;
    text-decoration: none;
    cursor: pointer;
}

.syc-more-signout-link:hover { color: var(--syc-danger, #b3261e); }

/* Deleting an account sits under the sign-out and reads as what it is. Muted rather than red at
   rest -- a permanently red row in a menu somebody opens to find "My sizes" is a menu that looks
   alarming all the time, and an alarm nobody can turn off stops being one. */
.syc-more-danger {
    color: var(--syc-muted, #5E6B6F);
    font-size: .9rem;
    border-top: 1px solid var(--syc-border, #E1DED6);
    margin-top: .25rem;
    padding-top: .75rem;
}

.syc-more-danger:hover { color: var(--syc-danger, #b3261e); }

/* The greeting at the top of the closet. */
.syc-closet-greeting {
    margin-block: .1rem 0;
    color: var(--syc-text-muted);
    font-size: .95rem;
}

/* ─── The greeting, and the screen name under it ────────────────────────────────────────────── */

/* The cover's place on the closet, under the bar. It was a white band above the bar, pulled up
   behind the clock; now the bar is first, as on every screen, and this is only spacing. */
.syc-greeting-band {
    margin: 0 0 .9rem;
}

.syc-greeting-text {
    margin: 0;
    font-family: var(--syc-font-sans, system-ui, -apple-system, "Segoe UI", sans-serif);
    font-size: 1.6rem;
    font-weight: 800;
    line-height: 1.2;
    letter-spacing: -0.01em;
    color: var(--syc-primary);
}

/* The screen's own name, and More. Sticky, because this is the one somebody reaches for. */
.syc-screen-title {
    position: sticky;
    top: 0;

    /* Above the page, above the greeting band it sits under, and above the closet's own sticky
       controls row at 1020.
 
       That last one is not about this bar -- it is about what the bar contains. A sticky element
       with a z-index starts a stacking context, and the More drawer is drawn inside this one, so
       the drawer's 1200 only ever meant 1200 *within here*. At 95 the closet's controls row came
       out through the middle of the open drawer and hid a menu item behind a filter pill. The bar
       has to outrank anything the drawer must cover, including the tab bar at 1035. */
    z-index: 1040;

    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .75rem;
    margin: 0 -1rem 1.5rem;
    padding: .7rem 1rem .8rem;
    background: var(--syc-header-bg);
    border-bottom: var(--syc-stripe-height, 3px) solid var(--syc-header-stripe, transparent);
}

.syc-screen-title-text {
    display: flex;
    align-items: center;
    gap: .55rem;
    margin: 0;
    font-family: var(--syc-font-heading, inherit);
    font-size: 1.6rem;
    font-weight: 700;
    line-height: 1.1;
    color: #fff;
}

.syc-screen-title-text .bi { font-size: 1.25rem; opacity: .9; }

/* A name that does not fit at full size gets a smaller one rather than a second line.

   A wrapped title is not just two lines: the bar changes height, everything sticky under it moves,
   and anything laid out beside the title -- an icon, say -- is suddenly centred against a block
   twice as tall. Two steps, because the alternative is measuring in JavaScript and showing a frame
   at the wrong size first. See ScreenTitle.LengthClass for where the thresholds come from. */
.syc-screen-title-text.syc-screen-title-long { font-size: 1.3rem; }
.syc-screen-title-text.syc-screen-title-longest { font-size: 1.1rem; }

/* The name and, under it, which one. Column so the two read as one block rather than as a title
   with something floating beside it. */
/* The name and, under it, which one -- centred between the hanger and the way back.

   It was a bare min-width with the two children left to stack themselves, and they did not: the
   subtitle came out on top of the title, greyed and half behind it. A column with a gap says the
   thing the markup was only implying. */
.syc-screen-title-block {
    flex: 1 1 auto;
    min-width: 0;

    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;

    /* The gap the details were reported as missing. They were overlapping the name before the
       column existed; with it they were merely close. */
    gap: .45rem;
}

.syc-screen-title-text { justify-content: center; text-align: center; }

/* Home, on the left of everything that is not home. Same size as the way back opposite it, so the
   two corners read as a pair rather than as a mark and a button. */
.syc-screen-home {
    display: grid;
    place-items: center;
    flex: 0 0 auto;
    width: 2.25rem;
    height: 2.25rem;
    border-radius: 999px;
    color: #fff;
}

.syc-screen-home svg { width: 1.6rem; height: 1.6rem; }
.syc-screen-home:hover { background: rgba(255, 255, 255, .16); color: #fff; }
.syc-screen-home:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }

/* "24-28 Sep - Cool - rain", in the bar rather than in the page.

   It used to be the first line of the page and scrolled away, so the answer to "what am I packing
   for" left the screen exactly when somebody scrolled down to pack. Here it stays.

   Which is also why the nights came out of it: this line is now paid for on every screenful
   rather than once, and the nights are the one part readable off the dates beside them. Quieter
   than the name on purpose -- it is the caption, not the heading, and a second line at full
   strength would make the bar shout twice.

   Ellipsised rather than wrapped. A wrap here costs height permanently, and this is a line
   somebody glances at rather than reads. */
.syc-screen-subtitle {
    margin: .1rem 0 0;
    /* Bolder and further down than it was. Reported as barely visible and sitting too close
       under the trip's name -- at .8rem, weight 500 and 85% opacity on a dark ground it was
       doing everything it could to be missed. This is the line that says what you are packing
       for, so it is allowed to be read. */
    /* Reported twice as too close and too faint. The gap on the block above was not enough on
       its own -- a line sitting directly under a 1.6rem heading needs air of its own as well. */
    margin-block-start: .35rem;
    font-size: .95rem;
    font-weight: 700;
    line-height: 1.35;
    color: #fff;
    opacity: 1;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.syc-screen-title-actions {
    display: flex;
    align-items: center;
    gap: .5rem;
}

/* The hamburger inside a screen title is on a coloured bar, so it inherits that bar's ink. */
.syc-screen-title .syc-nav-toggler { color: #fff; }

/* And so does anything else a screen puts up there. Select was drawn with the page's outline
   style -- grey on grey -- which on a dark blue bar is almost invisible. */
.syc-screen-title .btn-outline-secondary,
.syc-screen-title .btn-outline-primary {
    color: #fff;
    border-color: rgba(255, 255, 255, .55);
    background: transparent;
}

.syc-screen-title .btn-outline-secondary:hover,
.syc-screen-title .btn-outline-primary:hover {
    color: var(--syc-primary);
    background: #fff;
    border-color: #fff;
}

/* The one it toggles to: filled, so "selecting" reads as a state rather than a pressed button. */
.syc-screen-title .btn-secondary {
    color: var(--syc-primary);
    background: #fff;
    border-color: #fff;
}

.syc-screen-subtitle {
    margin: -.5rem 0 1rem;
    color: var(--syc-text-muted);
    font-size: .9rem;
}

/* ─── The lit tab ───────────────────────────────────────────────────────────────────────────── */

/* A filled pill rather than a change of ink.

   Colour alone was doing the whole job, and on a bar of five small icons a slightly different
   shade of one of them is not an answer to "where am I". A shape is. */
/* The lit tab, in the brand's blush rather than a tint of the page ink.

   A pale grey pill behind a blue icon was a shape without a colour -- readable if you looked for
   it, invisible if you glanced. The accent is the one warm thing in the palette and this is the
   one place on screen that has to answer "where am I" without being read. */
.syc-tab.active {
    color: var(--syc-nav-active-text, var(--syc-accent-dark));
}

/* A Tint pill with Brick in it, as the brand guide's bottom bar. */
.syc-tab.active .bi {
    background: var(--syc-nav-active-bg, var(--syc-accent-subtle));
    color: var(--syc-nav-active-text, var(--syc-accent-dark));
    border-radius: 999px;
    padding: .2rem .9rem;
}

.syc-tab.active .syc-tab-label { font-weight: 700; }

/* Clear of the notch. The drawer is fixed to the top of the viewport, which on a phone with a
   bezel-less screen is behind the clock. */
.syc-more-head {
    padding-top: calc(1rem + env(safe-area-inset-top, 0px));
}

.syc-more-drawer { padding-bottom: env(safe-area-inset-bottom, 0px); }

.syc-screen-title-logo { width: 2.2rem; height: 1.8rem; color: #fff; display: block; }

/* One bar, not two.

   The app header carried the brand and the hamburger above every screen, and the screen then drew
   its own heading underneath -- two bars saying where you are, one of them saying it in letters
   nobody needs repeated. The screen title is the bar on a phone now. It is hidden rather than
   removed because the header also carries ProfileSelector, which renders nothing and loads the
   active wardrobe that the closet and insights both read. */
@media (max-width: 991.98px) {
    .syc-header,
    .maui-header { display: none; }

    /* Everything clears the clock.
 
       Hiding the app header took away the only thing standing between a screen and the status bar,
       and every screen that is not one of the five destinations has no bar of its own -- so Closet
       setup opened with "Age range" printed across the battery icon. The page itself keeps the
       notch clear now, which is the version that works whether or not a screen has a bar.
 
       Both hosts are given the same figure so the pull-up below is one number rather than two. */
    .syc-main,
    .maui-main { padding-top: calc(1rem + env(safe-area-inset-top, 0px)); }

    .syc-content { padding-top: 0; }

    /* A bar at the top of a screen reaches past that padding and colours the notch itself, which
       is what makes it look like part of the phone rather than a strip below it. Only when it is
       the top: on the closet the greeting is above it, and pulling the bar up there dragged it
       over the greeting's last line. */
    .syc-screen-title:first-child {
        margin-top: calc(-1rem - env(safe-area-inset-top, 0px));
        padding-top: calc(.7rem + env(safe-area-inset-top, 0px));
    }

    /* And when it is not the top, it stops below the clock rather than under it. No screen has
       anything above its bar now -- the closet's greeting moved under it -- but a notice or a
       wait drawn first would otherwise stick the bar behind the status bar. */
    .syc-screen-title:not(:first-child) {
        top: env(safe-area-inset-top, 0px);
    }
}

/* On a wide screen the app header stays and does the navigating, so the screen title is a heading
   rather than a bar: no colour, no sticking, and the hamburger is redundant beside a header that
   already lists everywhere. */
@media (min-width: 992px) {
    .syc-screen-title {
        position: static;
        margin-inline: 0;
        padding-inline: 0;
        background: none;
        border-bottom: 1px solid var(--syc-border);
    }

    .syc-screen-title-text { color: var(--syc-text); }
    .syc-screen-title-logo { display: none; }
    .syc-screen-title .syc-nav-toggler { display: none; }

    /* And the buttons go back to ordinary ink.

       The rules above this media query paint anything in the title bar white, because on a phone
       that bar is dark blue. Here it is a plain heading on a white page -- so Select was white on
       white, with a white border, sitting invisibly beside Add. It was reported as "did we get rid
       of the select?", which is what an invisible button looks like from the outside.

       Stated in the app's own colours rather than reverted: `revert` rolls back to the previous
       cascade origin, and these are author styles like the ones they would roll back to, so it
       would land on unset and leave the button with no outline at all. */
    .syc-screen-title .btn-outline-secondary,
    .syc-screen-title .btn-outline-primary {
        color: var(--syc-primary);
        border-color: var(--syc-border);
        background: transparent;
    }

    .syc-screen-title .btn-outline-secondary:hover,
    .syc-screen-title .btn-outline-primary:hover {
        color: #fff;
        background: var(--syc-primary);
        border-color: var(--syc-primary);
    }

    /* Selecting is a state rather than a pressed button, so it stays filled -- in the page's ink
       here rather than the bar's white. */
    .syc-screen-title .btn-secondary {
        color: #fff;
        background: var(--syc-primary);
        border-color: var(--syc-primary);
    }
}

/* ─── The splash: a closet opening ──────────────────────────────────────────────────────────── */

/* One timeline, 4.7s, every part of it running the whole length and placing its own movement with
   percentage keyframes. That is what keeps five separate animations in step without a script to
   conduct them -- change the duration in one place and the whole sequence rescales.

   Everything is fill-mode: both, so the finished frame -- the mark, whole, with the baseline --
   is where each element rests. A browser that will not animate shows the logo rather than a gap. */
.syc-splash {
    --splash-run: 4.7s;
    width: 100%;

    /* Nine rem, not fifteen. At fifteen the drawing was 327px tall on a phone -- half the sign-in
       screen before the first field, and it pushed the form down past the fold.
 
       And clipped, which it was not: overflow:visible let the garment's final rise carry the
       hanger up out of the box and off the top of the screen, over the clock. Nothing needs to
       escape the viewBox; the movement was drawn to fit inside it. */
    max-width: 9rem;
    height: auto;
    display: block;
    margin-inline: auto;
    overflow: hidden;
}

.syc-splash path { fill: none; stroke-linecap: round; stroke-linejoin: round; }

.syc-splash-carcass,
.syc-splash-door > path { stroke: var(--syc-primary); stroke-width: 2.4; }

.syc-splash-feet,
.syc-splash-rail,
.syc-splash-handle { stroke: var(--syc-primary-light, #3E6C77); stroke-width: 2.4; }

.syc-splash-hook,
.syc-splash-shoulders { stroke: var(--syc-primary); stroke-width: 2.4; }

.syc-splash-base { stroke: var(--syc-accent, #EE5A3C); stroke-width: 3.4; }

/* .syc-splash path above sets fill:none and is a class plus an element, which outranks a class on
   its own -- so the garment was drawn with no fill at all and the animation ran without the one
   thing it is about. Matched on the same terms to settle it. */
.syc-splash path.syc-splash-body { fill: var(--syc-accent, #EE5A3C); stroke: none; }

/* 1 — the carcass draws itself. The dash is the path's own length, pulled away to reveal it. */
@keyframes syc-splash-draw {
    0%   { stroke-dashoffset: var(--len); }
    6%   { stroke-dashoffset: var(--len); }
    26%  { stroke-dashoffset: 0; }
    100% { stroke-dashoffset: 0; }
}

.syc-splash-carcass { --len: 760; stroke-dasharray: 760; animation: syc-splash-draw var(--splash-run) ease-in-out both; }
.syc-splash-feet    { --len: 40;  stroke-dasharray: 40;  animation: syc-splash-draw var(--splash-run) ease-in-out both; animation-delay: 0s; }
.syc-splash-rail    { --len: 100; stroke-dasharray: 100; animation: syc-splash-draw var(--splash-run) ease-in-out both; }

/* 2 — the doors appear with the carcass, swing back, then go with it. */
.syc-splash-door { transform-box: fill-box; }
.syc-splash-door-l { transform-origin: left center; animation: syc-splash-door-l var(--splash-run) ease-in-out both; }
.syc-splash-door-r { transform-origin: right center; animation: syc-splash-door-r var(--splash-run) ease-in-out both; }

@keyframes syc-splash-door-l {
    0%, 8%   { opacity: 0; transform: rotateY(0deg); }
    12%, 30% { opacity: 1; transform: rotateY(0deg); }
    46%      { transform: rotateY(-72deg); }
    66%      { opacity: 1; transform: rotateY(-72deg); }
    76%, 100%{ opacity: 0; transform: rotateY(-72deg); }
}

@keyframes syc-splash-door-r {
    0%, 8%   { opacity: 0; transform: rotateY(0deg); }
    12%, 30% { opacity: 1; transform: rotateY(0deg); }
    46%      { transform: rotateY(72deg); }
    66%      { opacity: 1; transform: rotateY(72deg); }
    76%, 100%{ opacity: 0; transform: rotateY(72deg); }
}

/* 4 — the wardrobe clears, leaving what was hung in it. */
.syc-splash-closet { animation: syc-splash-closet var(--splash-run) ease-in-out both; }

@keyframes syc-splash-closet {
    0%, 66%   { opacity: 1; }
    78%, 100% { opacity: 0; }
}

/* 3 — the garment drops onto the rail, swings itself still, then rises as the closet leaves. */
.syc-splash-garment {
    transform-box: fill-box;
    transform-origin: 50% 12%;
    animation: syc-splash-garment var(--splash-run) ease-in-out both;
}

@keyframes syc-splash-garment {
    0%, 44% { opacity: 0; transform: translateY(-150px) rotate(0deg) scale(1); }
    47%     { opacity: 1; }
    58%     { transform: translateY(-8px) rotate(0deg) scale(1); }
    62%     { transform: translateY(0) rotate(4.5deg) scale(1); }
    66%     { transform: translateY(0) rotate(-3deg) scale(1); }
    70%     { transform: translateY(0) rotate(1.5deg) scale(1); }
    74%     { transform: translateY(0) rotate(0deg) scale(1); }
    86%, 100% { opacity: 1; transform: translateY(-26px) rotate(0deg) scale(1.14); }
}

/* 5 — the garment itself clears, and the mark is what is left. */
.syc-splash-body { animation: syc-splash-body var(--splash-run) ease-in-out both; }

@keyframes syc-splash-body {
    0%, 80%   { opacity: 1; }
    90%, 100% { opacity: 0; }
}

/* Asked for less motion, the whole thing is simply the finished mark. */
@media (prefers-reduced-motion: reduce) {
    .syc-splash-carcass,
    .syc-splash-feet,
    .syc-splash-rail,
    .syc-splash-door-l,
    .syc-splash-door-r,
    .syc-splash-closet,
    .syc-splash-garment,
    .syc-splash-body { animation: none; }

    .syc-splash-closet,
    .syc-splash-body { opacity: 0; }

    .syc-splash-garment { transform: translateY(-26px) scale(1.14); }
}

/* The sign-in logo holder used to wrap a single glyph and sized itself around it. It now holds a
   drawing with room to move, so it gets a height rather than a font-size. */
.syc-auth-logo:has(.syc-splash),
.maui-logo:has(.syc-splash) {
    display: block;
    width: 100%;
    font-size: 0;
    margin-inline: auto;
    margin-block-end: .5rem;
}
/* The photography guide: prose, read once, standing in front of a wardrobe.

   It was a stack of cards, one rule each, which is the shape for things you dip into. This is read
   top to bottom before you start, so it is a page rather than a deck -- and a page is quicker to
   scan for the bit you half-remember. */
.syc-guide { max-width: 44rem; }

.syc-guide section { margin-block-end: 1.75rem; }

.syc-guide p { margin-block-end: .75rem; line-height: 1.55; }

.syc-guide ul { margin-block: .5rem 0; padding-inline-start: 1.25rem; }

.syc-guide li { margin-block-end: .5rem; line-height: 1.55; }

/* ─── The mark, where there is room for it ──────────────────────────────────────────────────── */

.syc-mark { display: block; margin-inline: auto; height: auto; }

/* An empty screen. Big enough to be the thing you look at, quiet enough not to be an instruction
   -- it replaces a generic Bootstrap glyph, so the room was already allowed for. */
.syc-mark-lg {
    width: 4.5rem;
    color: var(--syc-primary-light, #3E6C77);
    opacity: .75;
    margin-block-end: 1rem;
}

/* The end of a long list: a full stop, not a logo. */
.syc-mark-sm {
    width: 2rem;
    color: var(--syc-border);
}

.syc-mark-end { margin-block: 2.5rem 1rem; }

/* The empty states this replaced a glyph in sized it by font-size, which does nothing to an SVG. */
.syc-empty-state .syc-mark { font-size: 0; }

/* ─── The photography guide, set off ────────────────────────────────────────────────────────── */

/* Each heading in a soft blush box with a spine down its left and the mark before the words.

   It was three plain headings down a plain page, which is readable and says nothing about whose
   app it is. The colour is the accent already used for the lit tab and the hanger's baseline, so
   this is the brand's own pink rather than a decorative one. */
.syc-guide-boxed .syc-guide-heading {
    display: flex;
    align-items: center;
    gap: .5rem;
    margin-block: 1.75rem .6rem;
    padding: .5rem .75rem;
    font-size: 1.3rem;
    border-inline-start: 4px solid var(--syc-accent, #EE5A3C);
    border-radius: 0 var(--syc-radius) var(--syc-radius) 0;
    background: var(--syc-accent-subtle, #FDE1D8);
    color: var(--syc-primary);
}

.syc-mark-inline {
    width: 1.6rem;
    flex: 0 0 auto;
    margin: 0;
    color: var(--syc-primary);
}

/* The points, set off from the prose rather than flush with it, with the accent as the bullet. */
.syc-guide-boxed ul { list-style: none; padding-inline-start: .25rem; }

.syc-guide-boxed li {
    position: relative;
    padding-inline-start: 1.35rem;
    margin-block-end: .7rem;
}

.syc-guide-boxed li::before {
    content: "CF";
    position: absolute;
    inset-inline-start: .15rem;
    top: -.05em;
    font-size: .65rem;
    color: var(--syc-accent-dark, #B03A1E);
}

/* The way out, on a screen that has one. Same weight as the hamburger opposite it. */
.syc-screen-back {
    display: grid;
    place-items: center;
    flex: 0 0 auto;
    width: 2.25rem;
    height: 2.25rem;
    margin-inline-end: .1rem;
    border-radius: 999px;
    color: #fff;
    font-size: 1.15rem;
    text-decoration: none;
}

.syc-screen-back:hover { background: rgba(255, 255, 255, .16); color: #fff; }
.syc-screen-back:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }

/* On a wide screen the bar is a plain heading, so the arrow takes the page's ink. */
@media (min-width: 992px) {
    .syc-screen-back { color: var(--syc-text-muted); }
    .syc-screen-back:hover { background: var(--syc-surface-alt); color: var(--syc-text); }
}

/* The admin's view of somebody else's closet: a category heading over a table of its garments. */
.syc-admin-closet-head {
    display: flex;
    align-items: center;
    gap: .5rem;
    padding: .6rem .9rem;
    font-weight: 700;
    background: var(--syc-surface-alt);
    border-bottom: 1px solid var(--syc-border);
}

.syc-admin-closet-thumb { width: 3rem; }

/* A thumbnail you can tap to see larger (PhotoLook): the picture is the button. */
.syc-thumb-button {
    display: block;
    padding: 0;
    border: 0;
    background: none;
    cursor: zoom-in;
    border-radius: var(--syc-radius);
}

.syc-thumb-button:focus-visible {
    outline: 2px solid var(--syc-primary);
    outline-offset: 2px;
}

.syc-admin-closet-thumb img,
.syc-admin-closet-thumb .syc-outfit-noimg {
    width: 2.5rem;
    height: 2.5rem;
    object-fit: contain;
    display: block;
    border: 1px solid var(--syc-border);
    border-radius: var(--syc-radius);
    background: var(--syc-surface-alt);
}

/* The greeting, held back rather than blanked until the name is known: the line keeps its height,
   so nothing below it jumps, and the name arrives once instead of being swapped in. */
.syc-greeting-pending {
    visibility: hidden;
}

/* Back to the top of a long closet. Round, quiet, above the tab bar, and only once the page has
   scrolled well past the first screen -- nav.js sets syc-scrolled-far on the body.

   Centred, not in the right-hand corner: that corner belongs to the + that adds a garment, and a
   button that appears over it after a few screens of scrolling takes a tap meant for adding. */
.syc-back-to-top {
    position: fixed;
    left: 50%;
    transform: translateX(-50%);
    bottom: calc(66px + env(safe-area-inset-bottom, 0px) + 1rem);
    z-index: 1035;
    width: 44px;
    height: 44px;
    border-radius: 50%;
    border: 1px solid var(--syc-border);
    background: var(--syc-surface);
    color: var(--syc-primary);
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.15);
    font-size: 1.2rem;
    display: none;
    align-items: center;
    justify-content: center;
}

body.syc-scrolled-far .syc-back-to-top {
    display: flex;
}

/* Clear of the select bar, which sits on the same bottom edge while selecting. */
.syc-back-to-top.syc-back-to-top-lifted {
    bottom: calc(66px + env(safe-area-inset-bottom, 0px) + 4.5rem);
}

@media (min-width: 992px) {
    .syc-back-to-top { bottom: 1.5rem; }
}

/* Saving an edited garment, always in reach.

   The Save row is the last thing in a long form, so on a phone it is a scroll away from wherever
   you just corrected something -- and a save people have to go looking for is a save that does not
   happen. Round, bottom-right, the same shape as the + that adds a garment, because it is the same
   kind of promise: the one thing this screen is for. The row stays for Cancel. */
.syc-save-fab {
    position: fixed;
    right: 1rem;
    bottom: calc(66px + env(safe-area-inset-bottom, 0px) + 1rem);
    z-index: 1034;
    width: 60px;
    height: 60px;
    border-radius: 50%;
    border: none;
    padding: 0;
    background: var(--syc-primary);
    color: #fff;
    font-size: 1.6rem;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.28);
}

.syc-save-fab:disabled {
    opacity: 0.75;
}

@media (min-width: 992px) {
    /* No tab bar to clear on a wide screen, and the form's own Save row is in view there anyway. */
    .syc-save-fab { bottom: 1.5rem; }
}

/* While the keyboard is up, everything fixed to the bottom edge is in the way.

   iOS does not move fixed elements out from behind the keyboard: the tab bar, the + and this
   screen's Save simply float up and sit over the form, which is what a tester photographed. The
   keyboard cannot be detected directly, so nav.js watches the visual viewport and says so here. */
body.syc-keyboard-open .syc-tabbar,
body.syc-keyboard-open .syc-fab,
body.syc-keyboard-open .syc-back-to-top,
body.syc-keyboard-open .syc-save-fab {
    display: none !important;
}

/* A destination that is switched off for a round of testing -- see FeatureFlags.InsightsEnabled.

   Present and plainly unavailable, rather than gone. Five tabs are navigated by position as much
   as by name, and a bar that quietly becomes four reads as the app having lost something.

   text-light rather than text-muted: muted is the ordinary colour of an *enabled* tab here, so
   dimming to it would say nothing at all. */
.syc-tab-soon {
    color: var(--syc-text-light);
    opacity: 0.6;
    cursor: default;
}

.syc-tab-soon .syc-tab-label {
    /* The label stays the place's real name. The badge below carries the news, because
       syc-tab-label is nowrap inside a flex: 1 1 0 tab and "Coming soon" would run straight out
       of it on a 360px phone. */
    color: inherit;
}

.syc-tab-soon-badge {
    font-size: 0.55rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    line-height: 1;
    padding: 0.1rem 0.3rem;
    border-radius: var(--syc-radius);
    background: var(--syc-surface-alt);
    color: var(--syc-text-light);
    white-space: nowrap;
}

/* An outfit piece that is a link to the garment.

   syc-outfit-piece was a div until these became tappable, so nothing here ever had to stop a
   browser styling it as a link -- and without that, every garment name under a saved outfit comes
   out blue and underlined. The same two lines syc-worn-row carries, for the same reason. */
.syc-piece-link {
    text-decoration: none;
    color: inherit;
    display: block;
}

/* ---------------------------------------------------------------- the trip's own drawer

   What belongs to the trip rather than to a day: the pile you are choosing from, and the list of
   what is going in the case. Docked at the bottom so both are reachable from any day instead of
   being scrolled to -- the pile used to sit above the days and the list below all of them.

   Above the floating tab bar rather than behind it. 84px is the allowance this stylesheet already
   uses for that bar when it pads the page, so the two agree by construction rather than by two
   numbers that have to be kept the same by hand. The bar is phones-only, so on a wide screen the
   drawer drops to the bottom edge -- see the query below. */
.syc-trip-drawer {
    position: fixed;
    left: 0;
    right: 0;
    bottom: calc(84px + env(safe-area-inset-bottom, 0px));

    /* Under the tab bar at 1035 and under the header, over the page. */
    z-index: 1030;

    /* The app's own bar rather than a white strip.

       White on an off-white page is a rule and a shadow, and it read as part of the page rather
       than as the thing that is always there -- reported as "I don't think the white background is
       prominent enough on the bottom nav". Inside a trip this strip replaces the tab bar
       altogether, so it takes the tab bar's job and the header's colour: the screen is then
       bracketed top and bottom by the same slate, and everything between them is the trip. */
    background: var(--syc-header-bg);
    border-block-start: var(--syc-stripe-height, 3px) solid var(--syc-header-stripe, transparent);
    box-shadow: 0 -6px 20px rgba(0, 0, 0, .18);
}

@media (min-width: 992px) {
    /* No tab bar to sit above on a wide screen. */
    .syc-trip-drawer { bottom: 0; }
}

/* Two words and two counts. Closed, this strip is the whole drawer. */
.syc-trip-drawer-tabs {
    display: flex;
    gap: .25rem;
    padding: .35rem .5rem;
}

.syc-trip-drawer-tab {
    flex: 1 1 0;
    min-width: 0;

    /* Icon over label, the shape .syc-tab uses. This strip stands in for the tab bar inside a
       trip, so it reads as one rather than as a toolbar that happens to be at the bottom. */
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: .1rem;

    padding: .4rem .5rem;
    border: 1px solid transparent;
    border-radius: 999px;
    background: none;
    color: #fff;
    font-size: .85rem;
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.syc-trip-drawer-tab .bi { font-size: 1.15rem; }

/* The label under it, at the tab bar's size. */
.syc-trip-drawer-tab .syc-tab-label {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    font-size: .68rem;
    font-weight: 600;
    letter-spacing: .01em;
    white-space: nowrap;
}

/* The count beside Considering, legible on the slate. */
.syc-trip-drawer-tab .syc-type-count {
    background: rgba(255, 255, 255, .16);
    border-color: rgba(255, 255, 255, .28);
    color: #fff;
}

.syc-trip-drawer-tab.on {
    background: rgba(255, 255, 255, .14);
    border-color: var(--syc-accent);
    color: #fff;
}

/* The panel that used to open here was a 60vh sheet with its own scroll and category
   disclosures nested inside it -- three levels of scrolling in one control, and nowhere to put a
   row of colours. It is a full screen now; see .syc-picker. */


/* ------------------------------------------------------------- one day at a time, stepped

   This was a row of panels that snapped sideways: a real swipe, no JavaScript, and unusable.
   Each panel scrolled vertically, so a touch starting anywhere in the day was claimed by the
   panel's own scroller and only the heading would swipe. Reported exactly that way. Nested
   scrolling is arbitrated by the browser, not configured.

   Stepping needs no scroll container, which takes the rest of it with it: the fixed-height shell
   is gone and the page scrolls like a page again. */
.syc-day-step { display: block; }

/* Where you are, and the way through. The heading is the control rather than a label with
   controls beside it -- on a screen whose subject is the day, the day's name is the obvious place
   to hang them. */
.syc-day-step-head {
    display: flex;
    align-items: center;
    gap: .5rem;
    margin-block: .25rem 1rem;
}

/* No background. It was given one to stand out against a page of grey text, back when a dozen day
   headings shared a scroll; with one day on screen there is nothing left to stand out from, and a
   tinted box around the only heading reads as decoration. Size and weight do the work. */
.syc-day-step-name {
    flex: 1 1 auto;
    min-width: 0;

    display: flex;
    flex-direction: column;
    gap: .15rem;

    margin: 0;
    font-size: 1.35rem;
    font-weight: 800;
    line-height: 1.15;
    letter-spacing: -.01em;
    color: var(--syc-text);
    text-align: center;
}

/* The day, then its date. Two lines by construction rather than by luck: one long name used to
   wrap and a short one did not, so the same heading was two different heights. */
.syc-day-step-title { display: block; }

.syc-day-step-date {
    display: block;

    /* Up from .85rem. It is the second half of the heading rather than a footnote under it --
       "Getting there" and "Thu 24 Sep" are one answer to one question. */
    font-size: 1rem;
    font-weight: 600;
    color: var(--syc-text-muted);
    letter-spacing: 0;
}

.syc-day-step-name .syc-trip-night-occasion {
    font-size: .8rem;
    font-weight: 600;
    color: var(--syc-accent-dark);
}

/* Big enough to hit without looking. They are the only way between days now, so they are the most
   pressed controls on the screen -- 44px is the smallest target a thumb finds reliably. */
.syc-day-step-arrow {
    flex: 0 0 auto;
    width: 2.75rem;
    height: 2.75rem;

    display: grid;
    place-items: center;

    border: 1px solid var(--syc-accent-light);
    border-radius: 999px;
    background: var(--syc-accent-subtle);
    color: var(--syc-accent-dark);
    font-size: 1.25rem;
    line-height: 1;
}

.syc-day-step-arrow:disabled {
    opacity: .35;

    /* Still drawn, so the ends of the trip are visible rather than guessed at: a control that
       vanishes at the edge makes somebody wonder whether they mis-tapped. */
    border-color: var(--syc-border);
    background: var(--syc-surface-alt);
    color: var(--syc-text-muted);
}

/* The tab bar stands down inside a trip, and only inside a trip.

   Packing is a task you are in rather than one of five places you are at, and the bar was taking
   the bottom of the most crowded screen in the app.

   This was tried once and taken straight back out, because the back arrow reached the plans list
   and nothing reached the closet -- a screen you could only leave backwards. The hanger is what
   makes it right rather than a second attempt at the same idea: home is one tap from the left
   corner, the plans list one tap from the right, and both of those screens have the bar.

   Matched with :has() on a marker the page renders rather than a class JavaScript puts on <body>.
   A body class needs unsetting, the unset is what gets forgotten, and forgetting it would leave
   the whole app without navigation. A selector that stops matching when the page unmounts cannot.
   Where :has() is unsupported the rule is ignored and the bar simply stays. */
body:has(.syc-packing-screen) .syc-tabbar { display: none; }

/* And the drawer takes the space back, since there is no bar to clear. */
body:has(.syc-packing-screen) .syc-trip-drawer {
    /* Flush with the bottom of the screen, with the phone's safe area as padding inside the bar
       rather than as a gap under it.

       Offset by the inset, it floated a centimetre up the screen with the page scrolling through
       the strip underneath -- which is what stopped it reading as pinned at all. */
    bottom: 0;
    padding-block-end: env(safe-area-inset-bottom, 0px);
}

/* What the drawer is currently answering for. Without it a tap means one thing when the drawer
   was opened from the bottom and another when it was opened from a slot, and nothing on screen
   says which -- so you set a garment aside or you dress Friday evening, and you find out after. */
.syc-drawer-aim {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
    padding: .45rem .75rem;
    background: var(--syc-accent-subtle);
    border-block-end: 1px solid var(--syc-accent-light);
    color: var(--syc-accent-dark);
    font-size: .85rem;
}

/* .syc-slot-add held "Add to this one", a full-width line under every change of clothes. It is a
   button on the actions row now, beside the other three things you can do here. */

/* What the weather is doing on this change of clothes, beside its name.

   It was one line in the blue bar for the whole trip. Quiet here, because most days simply follow
   the trip and a week of identical pills would be noise -- and marked when a day answers for
   itself, so the exceptions are the ones the eye finds. */
.syc-slot-weather {
    margin-inline-start: .5rem;
    font-size: .78rem;
    font-weight: 600;
    color: var(--syc-text-muted);
}

.syc-slot-weather.own {
    padding: .1rem .45rem;
    border-radius: 999px;
    background: var(--syc-accent-subtle);
    color: var(--syc-accent-dark);
}

/* Rain on this one, as a toggle rather than a third entry in the band menu.

   Rain is not a temperature, which is the distinction the trip form already makes: a cool wet
   Friday has to be able to say both, and a menu holding Warm, Cool, Cold and Rainy forces a
   choice between them. */
.syc-slot-rain {
    flex: 0 0 auto;
    width: 2.1rem;
    height: 2.1rem;
    display: grid;
    place-items: center;

    border: 1px solid var(--syc-border);
    border-radius: 999px;
    background: var(--syc-surface);
    color: var(--syc-text-muted);
}

.syc-slot-rain.on {
    border-color: var(--syc-accent-dark);
    background: var(--syc-accent-subtle);
    color: var(--syc-accent-dark);
}

/* Wear home what you travelled out in. A toggle rather than a menu entry, because it is a yes or
   a no about two slots rather than a property of one. */
.syc-slot-samehome {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;

    padding: .3rem .7rem;
    border: 1px solid var(--syc-border);
    border-radius: 999px;
    background: var(--syc-surface);
    color: var(--syc-text-muted);
    font-size: .78rem;
    font-weight: 600;
    white-space: nowrap;
}

.syc-slot-samehome.on {
    border-color: var(--syc-accent-dark);
    background: var(--syc-accent-subtle);
    color: var(--syc-accent-dark);
}

/* The way back to the controls once a change of clothes has something on it.

   Quiet, and small: it is not an action, it is a way to reach the actions. On an empty slot there
   is no button at all and the row is simply there, because with nothing on the slot the controls
   are the only thing to look at. */
.syc-slot-tools-toggle {
    display: inline-flex;
    align-items: center;
    gap: .35rem;

    margin-block: .1rem .5rem;
    padding: .25rem .6rem;
    border: 1px solid var(--syc-border);
    border-radius: 999px;
    background: transparent;
    color: var(--syc-text-muted);
    font-size: .78rem;
    font-weight: 600;
}

.syc-slot-tools-toggle[aria-expanded="true"] {
    border-color: var(--syc-accent-light);
    background: var(--syc-accent-subtle);
    color: var(--syc-accent-dark);
}

/* What just happened to this change of clothes, said under the buttons that did it.

   Quiet and close. It was an alert at the top of the screen, which on a phone is six hundred
   pixels above the button it is about -- so the answer to "why did nothing happen" was on screen
   and nobody connected the two. */
.syc-slot-note {
    margin: .1rem 0 .6rem;
    padding: .5rem .7rem;
    border-radius: .5rem;
    background: var(--syc-accent-subtle);
    color: var(--syc-text);
    font-size: .85rem;
    line-height: 1.35;
}

/* A tap on a phone leaves :hover behind.

   There is no pointer to move away, so the last button tapped keeps its hover paint until
   something else is touched -- which on these two reads as "this one is selected", and Shuffle sat
   filled dark grey after being pressed as though it were a mode somebody had switched on. Only
   where there is no hover to speak of, so a mouse still gets its feedback. */
@media (hover: none) {
    .syc-slot-actions .btn:hover {
        background-color: transparent;
        color: var(--syc-accent-dark);
    }
}

/* --------------------------------------------------------------------- choosing clothes

   A sheet up over the trip, because choosing from a wardrobe is the whole task while you are doing
   it. The bottom bar is still the way in; this is what it opens. */

/* The dimmed ground behind it.

   The sheet was the full screen, over everything including the blue bar, and the honesty of that
   was the problem: a thing that fills the screen is a screen, and a screen you did not navigate to
   is one you are lost on. Nothing said what it was over or that it would go away again.

   Dimming the trip says both. It is also a second way out, because a dimmed thing invites a tap.

   Immediately under the sheet, and above the screen's bar at 1040 -- the bar is part of the trip
   this is laid over, and left bright it reads as chrome the sheet belongs to, which is the reading
   that made the sheet look like it had slid underneath something. */
.syc-picker-scrim {
    position: fixed;
    inset: 0;
    z-index: 1199;
    background: rgba(0, 0, 0, .45);

    /* The header is dimmed too. It is part of the trip this is laid over, and left bright it reads
       as chrome the sheet belongs to -- which is the reading that made the sheet look like it had
       slid underneath something. */

    animation: syc-scrim-in .22s ease-out;
}

@keyframes syc-scrim-in {
    from { opacity: 0; }
    to { opacity: 1; }
}

/* Out with the sheet rather than a frame before it, which would leave the sheet sliding down a
   screen that had already brightened. */
.syc-picker-scrim.closing { animation: syc-scrim-out .2s ease-in forwards; }

@keyframes syc-scrim-out {
    from { opacity: 1; }
    to { opacity: 0; }
}

/* Over everything, including the blue bar, and stopping short of the top.

   It sat under the bar before, which is why the way back looked missing: the bar was visible above
   a screen that had replaced the page, so the arrow belonged to something you could not see. The
   answer is not to cover the whole window but to sit over it and say so -- the strip of dimmed
   trip above the rounded corners is the thing that reads as "laid over", and it is where the eye
   goes when somebody wants out.

   1060 clears the header at 1040 and the tab bar at 1035. */
.syc-picker {
    position: fixed;
    /* Onto the bar, not under it and not below it.

       Under it was the first bug -- the sheet filled the window and the bar sat over its title.
       Below it was this fix and it read as a seam: the sheet's square top edge met the bar's
       bottom edge exactly, so what looked like a drawer coming up looked like a second half of
       the header. Asked for directly: "it should be slightly covering the top nav bar, with
       rounded corners and the navbar being grayed out."

       So it rises a little way into the bar. The corners land on dimmed blue, which is the one
       arrangement that reads as a sheet over a screen rather than as part of it.

       Measured from the top of the glass rather than from the bar. The bar's height is published
       by nav.js and has been wrong on this screen -- see the note there -- and a sheet that has to
       clear something is a sheet that breaks when the measurement is off. The safe area is a
       number the phone itself supplies and cannot be stale. */
    inset-block-start: calc(env(safe-area-inset-top, 0px) + 2.25rem);
    inset-inline: 0;
    inset-block-end: 0;

    /* Decisively above the screen's own bar at 1040 rather than narrowly above it. 1060 should
       have been enough and the bar went on painting over the sheet, so this stops being a question
       worth re-asking on a device that cannot be debugged from here. */
    z-index: 1200;

    /* The corners are the other half of saying it is a sheet, so nothing may paint over them.
       clip rather than hidden: hidden makes a scroll container, and a scroll container in here
       would break any position:sticky the clothes list ever grows. */
    overflow: clip;

    display: flex;
    flex-direction: column;

    background: var(--syc-surface);

    /* Rounded at the top only, because it came from the bottom and the corners are what say so.
       Bigger than a card's radius: this is the one on the screen that has to read from a glance. */
    border-start-start-radius: 1.25rem;
    border-start-end-radius: 1.25rem;

    /* Lifted off the page it covers. Without it a light sheet on a dimmed page meets it at a line
       drawn by the dimming alone, which goes when the scrim does. */
    box-shadow: 0 -.5rem 1.75rem rgba(0, 0, 0, .18);

    padding-block-end: env(safe-area-inset-bottom, 0px);

    /* Up from the bottom rather than simply appearing. A sheet that materialises has no direction,
       so nothing about it says which gesture puts it away again. */
    animation: syc-sheet-up .22s cubic-bezier(.2, .8, .3, 1);
}

@keyframes syc-sheet-up {
    from { transform: translateY(100%); }
    to { transform: translateY(0); }
}

/* Leaving, which has to be a class rather than the absence of one: an element removed from the
   DOM cannot animate on its way out. */
.syc-picker.closing { animation: syc-sheet-down .2s ease-in forwards; }

@keyframes syc-sheet-down {
    from { transform: translateY(0); }
    to { transform: translateY(100%); }
}

@media (prefers-reduced-motion: reduce) {
    .syc-picker,
    .syc-picker.closing,
    .syc-picker-scrim,
    .syc-picker-scrim.closing { animation: none; }
}

.syc-picker-head {
    display: flex;
    align-items: center;
    gap: .75rem;
    padding: .9rem 1rem .75rem;
    border-block-end: 1px solid var(--syc-border);
}

/* What order, and what colour: the sheet's own control row, under its title.

   The colour menu used to sit here alone and filled the width of the sheet, because the label
   around it is a block -- see .syc-colour-filter. */
.syc-picker-controls {
    display: flex;
    align-items: center;
    gap: .5rem;
    padding: .6rem 1rem;
    border-block-end: 1px solid var(--syc-border);
}

/* Four menus will not sit on one phone line, so they wrap into two rather than scrolling
   sideways: these are questions to read and choose from, not chips to flick past. */
.syc-picker-controls { flex-wrap: wrap; }

.syc-picker-controls > * { flex: 0 1 auto; min-width: 0; }

/* How wide the closet is, in the row with the three menus rather than under them.

   A button rather than a link: the three things beside it are controls with edges, and a bare
   underlined sentence among them reads as a caption. Quieter than a primary action, because it is
   one of four answers to one question and not the point of the screen. */
.syc-picker-showall {
    flex: 0 0 auto;
    padding: .3rem .7rem;
    border: 1px solid var(--syc-border);
    border-radius: 999px;
    background: var(--syc-surface);
    color: var(--syc-accent-dark);
    font-size: .8rem;
    font-weight: 600;
    white-space: nowrap;
}

.syc-picker-filter { display: inline-flex; align-items: center; }
.syc-picker-filter .form-select { width: auto; min-width: 7rem; max-width: 10rem; }

/* Top left, and small. The sheet covers the app, so the way out has to be the first thing the eye
   lands on -- and the top left is where a closed thing is closed from. */
.syc-picker-close {
    flex: 0 0 auto;
    width: 2rem;
    height: 2rem;
    display: grid;
    place-items: center;
    border: none;
    border-radius: 999px;
    background: var(--syc-surface-alt);
    color: var(--syc-text);
    font-size: .9rem;
}

/* It carries the slot's name when the picker is dressing one, which is the whole reason a title
   is here rather than a banner further down. */
.syc-picker-title {
    margin: 0;
    font-size: 1.1rem;
    font-weight: 700;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* One row, scrolled sideways rather than wrapped into a block that pushes the clothes off screen.
   A wardrobe has a handful of colours in it and they fit; a wrap would cost two or three rows on
   the wardrobes that do not. */
.syc-picker-colours {
    display: flex;
    gap: .4rem;
    overflow-x: auto;
    padding: .6rem 1rem;
    border-block-end: 1px solid var(--syc-border);
    scrollbar-width: none;
}

.syc-picker-colours::-webkit-scrollbar { display: none; }

.syc-colour-chip {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    gap: .35rem;

    padding: .35rem .7rem;
    border: 1px solid var(--syc-border);
    border-radius: 999px;
    background: var(--syc-surface);
    color: var(--syc-text);
    font-size: .8rem;
    font-weight: 600;
    white-space: nowrap;
}

.syc-colour-chip.on {
    border-color: var(--syc-primary);
    background: var(--syc-primary);
    color: #fff;
}

/* The swatch itself. Ringed, so white and cream are still discs rather than nothing. */
.syc-colour-dot {
    width: .9rem;
    height: .9rem;
    border-radius: 999px;
    border: 1px solid rgba(0, 0, 0, .25);
}

.syc-picker-body {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;

    /* -webkit-overflow-scrolling: touch is gone from here, and that is the other half of why the
       heading floated.
    
       It puts the scroller on its own compositing layer in WebKit, and a position:sticky child of
       such a layer is composited against the wrong thing: it lags the scroll, drifts off the edge
       it is supposed to be pinned to, and lets content show through where it should be covered.
       Which is exactly what was reported -- the heading "floating", with garments visible both
       above and below it.
    
       It has bought nothing since iOS 13, where momentum scrolling became the default. Removing it
       costs nothing anywhere and is the difference between a sticky heading that works on a phone
       and one that only works in a desktop browser.
    
       No padding at the top either, so a pinned heading is flush against the controls above it.
    
       There was .75rem here, and a sticky child sticks to the scrollport rather than to the
       content -- so the heading pinned itself that much down the screen and garments scrolled
       through the strip above it. Reported as the heading "floating", with items visible both
       above and below it.
    
       The clothes still want the gap when the list is at its start, so the first group carries it
       as a margin instead: it scrolls away, which is what a top margin should do. */
    padding: 0 1rem 1.5rem;
}

.syc-picker-body > .syc-type-group:first-of-type,
.syc-picker-body > .syc-slot-grid:first-of-type,
.syc-picker-body > p:first-of-type { margin-block-start: .75rem; }

/* The sentence between choosing clothes and packing them, on the trip itself.

   Said once, in the one moment it is the whole question -- clothes set aside and nothing dressed
   yet -- so it can afford to sit above the day rather than beside it. Tinted rather than muted:
   muted grey is what this screen uses for things you may ignore, and this is the one line on it
   that answers the question somebody actually has. */
.syc-trip-lead {
    margin: 0 0 .75rem;
    padding: .6rem .8rem;
    border-radius: .6rem;
    background: var(--syc-accent-subtle);
    color: var(--syc-text);
    font-size: .9rem;
    line-height: 1.35;
}

/* The sentence over the closet on a brand-new trip. */
.syc-picker-lead {
    margin: 0;
    padding: .75rem 1rem 0;
    font-size: .95rem;
    font-weight: 600;
    color: var(--syc-text-muted);
}

/* Finished choosing. Round, in the corner the thumb is already in, and big enough to be the
   obvious end of the step rather than a word in the header competing with the title. */
.syc-picker-confirm {
    position: absolute;
    inset-block-end: calc(1.25rem + env(safe-area-inset-bottom, 0px));
    inset-inline-end: 1.25rem;

    width: 3.5rem;
    height: 3.5rem;
    display: grid;
    place-items: center;

    border: none;
    border-radius: 999px;
    background: var(--syc-accent-dark);
    color: #fff;
    font-size: 1.5rem;
    box-shadow: 0 6px 20px rgba(0, 0, 0, .22);
}

/* ----------------------------------------------------------------- when the trip is

   One calendar for both dates. See TripDateRange for why it is not two date inputs. */
.syc-cal {
    border: 1px solid var(--syc-border);
    border-radius: var(--syc-radius);
    background: var(--syc-surface);
    overflow: hidden;
}

/* The one row that is the same on every month, so it does not scroll away with them. */
.syc-cal-weekdays {
    position: sticky;
    top: 0;
    z-index: 2;

    display: grid;
    grid-template-columns: repeat(7, 1fr);

    padding: .5rem .5rem .4rem;
    background: var(--syc-surface);
    border-block-end: 1px solid var(--syc-border);

    font-size: .72rem;
    font-weight: 700;
    color: var(--syc-text-muted);
    text-align: center;
}

/* Months run on rather than sitting behind arrows: a next-month button hides whether the trip
   crosses a month end, which is the thing everybody checks. Capped so the form is still a form. */
.syc-cal-scroll {
    max-height: 22rem;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    padding: .25rem .5rem .5rem;
}

.syc-cal-month + .syc-cal-month { margin-block-start: .75rem; }

.syc-cal-month-name {
    margin: .5rem .25rem .4rem;
    font-size: 1rem;
    font-weight: 700;
}

.syc-cal-grid {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    row-gap: .15rem;
}

.syc-cal-blank { aspect-ratio: 1; }

.syc-cal-day {
    aspect-ratio: 1;
    display: grid;
    place-items: center;

    border: none;
    background: none;
    color: var(--syc-text);
    font-size: .9rem;
    font-weight: 600;

    /* Round, and the band between them square, so a range reads as one shape with two ends rather
       than as a row of separate discs. */
    border-radius: 999px;
}

/* The days in between. Drawn under the ends by sitting behind a square background on the cell,
   which is what makes the run continuous across a week. */
.syc-cal-day.between {
    background: var(--syc-accent-subtle);
    border-radius: 0;
    color: var(--syc-accent-dark);
}

.syc-cal-day.start,
.syc-cal-day.end {
    background: var(--syc-accent-dark);
    color: #fff;
}

/* Square on the inward side, so each end meets the band rather than floating beside it. */
.syc-cal-day.start { border-start-end-radius: 0; border-end-end-radius: 0; }
.syc-cal-day.end { border-start-start-radius: 0; border-end-start-radius: 0; }

/* A single chosen day -- an event, or a start with no end yet -- is round on both sides, because
   there is no band for it to meet. TripDateRange marks such a day as both ends. */
.syc-cal-day.start.end { border-radius: 999px; }

.syc-cal-day.today { outline: 1px solid var(--syc-accent); outline-offset: -3px; }

/* What has been chosen, in words. The shading answers it while you are looking; this answers it
   after you have scrolled. */
.syc-cal-readout {
    margin: 0;
    padding: .6rem .75rem;
    border-block-start: 1px solid var(--syc-border);
    background: var(--syc-surface-alt);
    font-size: .85rem;
    font-weight: 600;
    color: var(--syc-text);
}

/* ===== Admin -> Users: two lines a person, and a bar for sample closets =====
   It was a seven-column table with five controls in the last cell, which wrapped into a cramped
   stack on every row. Now line one says who somebody is, line two what they have and what can
   be done about it, and the one action meant for several people at once -- a sample closet --
   lives in a bar above the list instead of a menu on each row. */

.syc-user-bulk {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    padding: 0.75rem 1rem;
    background: var(--syc-surface-alt);
    border-bottom: 1px solid var(--syc-border);
    position: sticky;
    top: 0;
    z-index: 2;
}

.syc-user-bulk-count {
    font-weight: 600;
    font-size: 0.875rem;
    min-width: 7.5rem;
}

/* Select-all, the search box and the count, on one line. */
.syc-user-find {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem 0.75rem;
}

.syc-user-find .syc-user-check {
    padding-top: 0;
    align-items: center;
}

.syc-user-search {
    flex: 1 1 14rem;
    max-width: 24rem;
}

.syc-user-hidden-note {
    font-weight: 400;
    color: var(--syc-text-muted);
}

.syc-user-none {
    padding: 1rem;
    color: var(--syc-text-muted);
}

/* Everything about sample closets, boxed together so it reads as one tool. */
.syc-sample-panel {
    padding: 0.6rem 0.75rem;
    border: 1px solid var(--syc-border);
    border-radius: var(--syc-radius);
    background: var(--syc-surface);
}

.syc-sample-panel-head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.25rem 1rem;
}

.syc-sample-panel-title {
    margin: 0;
    font-size: 0.95rem;
    font-weight: 600;
}

.syc-sample-panel-edit {
    margin-left: auto;
    font-size: 0.85rem;
}

.syc-sample-panel-hint {
    margin: 0.2rem 0 0.5rem;
    font-size: 0.8rem;
    color: var(--syc-text-muted);
}

.syc-sample-panel-body {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem 1rem;
}

.syc-user-bulk-sets {
    display: flex;
    gap: 0.25rem;
    margin: 0;
    padding: 0;
    border: 0;
}

/* The two closets as a segmented pair: a radio each, drawn as one control. */
.syc-user-set {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.25rem 0.7rem;
    border: 1px solid var(--syc-border);
    border-radius: 999px;
    background: var(--syc-surface);
    font-size: 0.875rem;
    cursor: pointer;
}

.syc-user-set:has(input:checked) {
    border-color: var(--syc-primary);
    background: var(--syc-accent-subtle);
}

.syc-user-set .form-check-input {
    margin: 0;
}

.syc-user-bulk-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    margin-left: auto;
}

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

.syc-user-row {
    display: grid;
    grid-template-columns: 2.25rem 1fr;
    row-gap: 0.3rem;
    padding: 0.7rem 1rem;
    border-bottom: 1px solid var(--syc-border);
}

.syc-user-row:last-child {
    border-bottom: 0;
}

.syc-user-row.is-selected {
    background: var(--syc-accent-subtle);
}

.syc-user-check {
    grid-row: 1 / span 2;
    display: flex;
    align-items: flex-start;
    padding-top: 0.2rem;
    cursor: pointer;
}

.syc-user-line {
    grid-column: 2;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.25rem 0.75rem;
    min-width: 0;
}

.syc-user-name {
    font-weight: 600;
}

.syc-user-email {
    color: var(--syc-text-muted);
    overflow-wrap: anywhere;
}

.syc-user-tags {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    margin-left: auto;
}

.syc-user-preview {
    display: inline-flex;
    align-items: center;
    font-size: 0.8rem;
    color: var(--syc-text-muted);
    white-space: nowrap;
    margin: 0;
}

.syc-user-role {
    width: auto;
    padding-top: 0.1rem;
    padding-bottom: 0.1rem;
}

.syc-user-meta {
    font-size: 0.85rem;
    color: var(--syc-text-muted);
}

.syc-user-meta strong {
    color: var(--syc-text);
}

.syc-user-actions {
    display: inline-flex;
    flex-wrap: wrap;
    gap: 0.35rem;
    margin-left: auto;
}

/* Narrow screens: the tags and actions drop under the text instead of squeezing beside it. */
@media (max-width: 640px) {
    .syc-user-tags,
    .syc-user-actions,
    .syc-user-bulk-actions,
    .syc-sample-panel-edit {
        margin-left: 0;
    }

    .syc-user-search {
        max-width: none;
    }
}

/* ===== Folding sections: the phone's admin screen, and each list inside it =====
   A header you tap to open, and a body that only exists while it is open. Buttons rather than
   <details> so what is inside loads only when somebody asks for it. */

.syc-fold,
.syc-lookup-group {
    background: var(--syc-surface);
    border: 1px solid var(--syc-border);
    border-radius: var(--syc-radius-lg, 12px);
    margin-bottom: 0.75rem;
    overflow: hidden;
}

.syc-lookup-group {
    border-radius: var(--syc-radius);
    margin-bottom: 0.5rem;
}

.syc-fold-head,
.syc-lookup-group-head {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.85rem 1rem;
    background: none;
    border: 0;
    text-align: left;
    color: var(--syc-text);
    font-weight: 600;
}

.syc-lookup-group-head {
    padding: 0.65rem 0.85rem;
    font-size: 0.95rem;
}

.syc-fold-title {
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
}

.syc-fold-title > i {
    color: var(--syc-primary);
    margin-top: 0.1rem;
}

.syc-fold-hint {
    display: block;
    font-weight: 400;
    font-size: 0.8rem;
    color: var(--syc-text-muted);
}

.syc-fold-head .bi-chevron-right,
.syc-lookup-group-head .bi-chevron-right {
    transition: transform var(--syc-transition, 0.2s ease);
    color: var(--syc-text-muted);
}

.syc-fold.is-open > .syc-fold-head .bi-chevron-right,
.syc-lookup-group.is-open > .syc-lookup-group-head .bi-chevron-right {
    transform: rotate(90deg);
}

.syc-fold-body {
    padding: 0 1rem 1rem;
}

.syc-lookup-group-body {
    padding: 0 0.85rem 0.85rem;
}

/* A list's rows, stacked: name and details on the left, the two buttons beside or beneath. */
.syc-lookup-rows {
    list-style: none;
    margin: 0;
    padding: 0;
}

.syc-lookup-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.4rem 0.75rem;
    padding: 0.55rem 0;
    border-top: 1px solid var(--syc-border);
}

.syc-lookup-row.is-inactive .syc-lookup-name {
    color: var(--syc-text-muted);
    text-decoration: line-through;
}

.syc-lookup-row-text {
    min-width: 0;
    flex: 1 1 10rem;
}

.syc-lookup-name {
    display: block;
    font-weight: 500;
}

.syc-lookup-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem 0.6rem;
    font-size: 0.8rem;
    color: var(--syc-text-muted);
}

.syc-lookup-row-actions {
    display: flex;
    gap: 0.35rem;
}

/* The phone's users, one card each. */
.syc-admin-users {
    list-style: none;
    margin: 0;
    padding: 0;
}

.syc-admin-user {
    display: grid;
    grid-template-columns: 1fr auto;
    column-gap: 0.75rem;
    row-gap: 0.15rem;
    padding: 0.65rem 0;
    border-top: 1px solid var(--syc-border);
}

.syc-admin-user > :not(.syc-admin-user-open) {
    grid-column: 1;
}

.syc-admin-user-open {
    grid-column: 2;
    grid-row: 1 / span 3;
    align-self: center;
}

.syc-admin-user-who {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem;
}

.syc-admin-user-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 0.15rem 0.7rem;
    font-size: 0.8rem;
    color: var(--syc-text-muted);
}

.syc-admin-user-meta strong {
    color: var(--syc-text);
}

/* ── Work week ─────────────────────────────────────────────────────────────────────────────── */

/* The day's weather sits on the day's heading line, quieter than the day: it is why the outfit is
   what it is, not what somebody scrolls for. Not uppercase, unlike the day name beside it. */
.syc-week-weather {
    font-size: .8rem;
    font-weight: 400;
    color: var(--syc-text-muted);
}

.syc-week-hint {
    color: var(--syc-text-muted);
    background: var(--syc-surface-alt);
    border-radius: var(--syc-radius);
    padding: .5rem .75rem;
}

/* ── Today card ────────────────────────────────────────────────────────────────────────────── */

/* Inside the closet cover, under the greeting (see TodayCard): the weather in one white line, at
   most one tip in frost, and Today's outfit as a white pill -- the card's own button. Sized for
   the cover's Deep Teal; every colour here is over 7:1 on it. */
.syc-cover .syc-today-weather {
    margin: .4rem 0 0;
    font-size: .92rem;
    font-weight: 600;
    line-height: 1.3;
    color: #FFFFFF;
}
.syc-cover .syc-today-tip {
    margin: .15rem 0 0;
    font-size: .8rem;
    line-height: 1.3;
    color: #CFE7F1;
}
.syc-cover .syc-today-address { color: #FFFFFF; font-size: inherit; vertical-align: baseline; }

.syc-today-open {
    display: inline-flex;
    align-items: center;
    margin-top: .6rem;
    padding: .3rem .85rem;
    border: 0;
    border-radius: 999px;
    background: #FFFFFF;
    color: var(--syc-primary);
    font-size: .85rem;
    font-weight: 700;
    box-shadow: 0 2px 6px rgba(0, 0, 0, .18);
}
.syc-today-open:active { transform: translateY(1px); }

.syc-today-worn { font-size: .8rem; font-weight: 600; color: var(--syc-success); }

/* A card with Today in it carries three more lines, so the greeting comes down a size to keep it
   from wrapping onto a third, and the fan of photographs narrows so the weather keeps one line. */
.syc-cover:has(.syc-today-weather) .syc-cover-greeting { font-size: 1.3rem; }
.syc-cover:has(.syc-today-weather) { gap: .5rem; padding-inline-end: .75rem; }
.syc-cover:has(.syc-today-weather) .syc-cover-photo { width: 52px; height: 66px; }
.syc-cover:has(.syc-today-weather) .syc-cover-photo + .syc-cover-photo { margin-inline-start: -16px; }

/* Today's pop-up: clearly a card over the closet, to be closed once decided. It ran from the top
   of the screen to the bottom, with its title under the clock: "it looks like it is taking the
   whole screen and I want it to be clear that it is a pop-up." So a margin all round, clear of
   the notch and the home bar, the closet showing behind, and the title in a band of its own. */
.syc-today-modal .modal-dialog {
    --syc-today-gap-top: calc(env(safe-area-inset-top) + 2.5rem);
    --syc-today-gap-bottom: calc(env(safe-area-inset-bottom) + 2rem);
    max-width: min(30rem, calc(100% - 2.5rem));
    margin: var(--syc-today-gap-top) auto var(--syc-today-gap-bottom);
    height: auto;
    min-height: calc(100% - var(--syc-today-gap-top) - var(--syc-today-gap-bottom));
}
.syc-today-modal .modal-content {
    /* Its own text colour: it sits inside the closet's cover, whose text is white, and the title
       came out white on the pale band -- "the title is white on white background." */
    color: var(--syc-text);
    max-height: calc(100dvh - var(--syc-today-gap-top) - var(--syc-today-gap-bottom));
    border: 0;
    border-radius: 1rem;
    box-shadow: 0 1rem 2.5rem rgba(0, 0, 0, .35);
}
.syc-today-modal .modal-header {
    align-items: flex-start;
    padding: 1rem 1rem .75rem;
    background: color-mix(in srgb, var(--syc-primary) 7%, #FFFFFF);
    border-bottom: 1px solid var(--syc-border);
    border-radius: 1rem 1rem 0 0;
}
.syc-today-modal .modal-title {
    color: var(--syc-primary);
    font-family: var(--syc-font-heading);
    font-size: 1.3rem;
    font-weight: 700;
    margin-bottom: .15rem !important;
}
.syc-today-modal .modal-body { padding: .75rem 1rem; }
/* Three pieces a row, not two: the outfit seen at once rather than scrolled through. */
.syc-today-modal .syc-slot-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.syc-today-modal .syc-slot-piece-name { font-size: .72rem; }

/* Wear this across the top; Something else and Close the same size under it. */
.syc-today-actions {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: .5rem;
    padding: .75rem 1rem;
}
.syc-today-actions > * { margin: 0; }
.syc-today-actions .btn {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 2.75rem;
    padding: .5rem .75rem;
    font-size: .95rem;
    white-space: nowrap;
}
.syc-today-actions .syc-today-action-wide { grid-column: 1 / -1; }

/* Swapping a piece: the one going is dimmed, and what could replace it opens underneath. */
.syc-piece-swapping .syc-slot-photo { opacity: .45; }

.syc-swap-panel {
    margin-top: .75rem;
    padding: .75rem;
    border: 1px solid var(--syc-border);
    border-radius: var(--syc-radius);
    background: var(--syc-surface-alt);
}

.syc-swap-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
    margin-bottom: .5rem;
    font-size: .9rem;
}

/* My week: "Work week" and "Weekend" over their days. */
.syc-week-group {
    font-size: .8rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .06em;
    color: var(--syc-text-muted);
    margin: 1.25rem 0 .5rem;
}

.syc-week-dress {
    font-size: .75rem;
    font-weight: 600;
    padding: .05rem .45rem;
    border-radius: 999px;
    background: var(--syc-surface-alt);
    color: var(--syc-text-muted);
}

/* The outfit under the notification preview: small, in a row, as what tapping it opens. */
.syc-notify-items {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
    max-width: 24rem;
}

.syc-notify-item { width: 5rem; margin: 0; }

.syc-notify-item img,
.syc-notify-item .syc-outfit-noimg {
    width: 5rem;
    aspect-ratio: 1;
    object-fit: contain;
    border: 1px solid var(--syc-border);
    border-radius: var(--syc-radius);
    background: var(--syc-surface-alt);
}

.syc-notify-item figcaption {
    font-size: .7rem;
    line-height: 1.2;
    color: var(--syc-text-muted);
    overflow-wrap: anywhere;
}

.syc-today-head {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: .25rem .6rem;
    margin-block-end: .5rem;
}

.syc-today-title {
    font-weight: 700;
    font-size: .95rem;
    text-transform: uppercase;
    letter-spacing: .04em;
}

.syc-today-tip {
    font-size: .85rem;
    color: var(--syc-text-muted);
    margin-block-end: .5rem;
}

/* ── Notifications ─────────────────────────────────────────────────────────────────────────── */

.syc-notify-time { max-width: 10rem; }

.syc-notify-heading {
    font-size: .95rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .04em;
    margin: 1.25rem 0 .25rem;
}

/* Drawn as a lock-screen notification is: a rounded, slightly translucent slab with the app's
   name small and grey above a bold title and a few lines of body. Close enough to judge the
   words at the size they will be read, without pretending to be the phone's own. */
.syc-notify-preview {
    max-width: 24rem;
    padding: .65rem .85rem .75rem;
    border-radius: 1.1rem;
    background: color-mix(in srgb, var(--syc-surface-alt) 85%, transparent);
    border: 1px solid var(--syc-border);
    box-shadow: 0 2px 10px rgb(0 0 0 / .08);
}

.syc-notify-app {
    display: flex;
    align-items: center;
    gap: .4rem;
    font-size: .7rem;
    letter-spacing: .03em;
    color: var(--syc-text-muted);
    margin-block-end: .3rem;
}

.syc-notify-icon {
    display: inline-flex;
    width: 1.1rem;
    height: 1.1rem;
    overflow: hidden;
    border-radius: .3rem;
}

.syc-notify-icon > * { width: 100%; height: 100%; }

.syc-notify-title { font-weight: 600; font-size: .95rem; }

/* Four lines and an ellipsis, as the lock screen cuts it -- so a message too long shows here too. */
.syc-notify-body {
    font-size: .9rem;
    line-height: 1.3;
    display: -webkit-box;
    -webkit-line-clamp: 4;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* ── Insights ──────────────────────────────────────────────────────────────────────────────── */

/* What an occasion is short of: its own line under the counts, in the accent the thin bar uses. */
.syc-insight-limit { display: block; color: var(--syc-accent, #EE5A3C); font-weight: 600; }

.syc-insight {
    background: var(--syc-surface);
    border: 1px solid var(--syc-border);
    border-radius: var(--syc-radius);
    padding: .9rem 1rem;
    margin-bottom: 1rem;
}

.syc-insight-title {
    font-size: .95rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .04em;
    margin: 0 0 .75rem;
}

.syc-insight-subtitle {
    font-size: .85rem;
    font-weight: 700;
    margin: 1rem 0 .4rem;
}

/* A labelled bar and its number: occasions, weathers and colour families all read the same way. */
.syc-insight-row {
    display: grid;
    grid-template-columns: minmax(6rem, 9rem) 1fr auto;
    align-items: center;
    gap: .6rem;
    margin-bottom: .35rem;
    font-size: .9rem;
}

.syc-insight-label { display: inline-flex; align-items: center; gap: .3rem; min-width: 0; }

.syc-insight-bar {
    height: .55rem;
    border-radius: 999px;
    background: var(--syc-surface-alt);
    overflow: hidden;
}

.syc-insight-bar > span {
    display: block;
    height: 100%;
    border-radius: inherit;
    background: var(--syc-primary);
}

.syc-insight-bar.thin > span { background: var(--syc-accent, #EE5A3C); }

.syc-insight-num { font-variant-numeric: tabular-nums; font-weight: 600; }

.syc-insight-sub {
    font-size: .75rem;
    color: var(--syc-text-muted);
    margin: -.15rem 0 .5rem;
    padding-left: .1rem;
}

.syc-insight-note {
    font-size: .82rem;
    color: var(--syc-text-muted);
    margin: .5rem 0 0;
}

.syc-insight-buy {
    padding: .55rem 0;
    border-top: 1px solid var(--syc-border);
}

.syc-insight-buy:first-of-type { border-top: 0; }

.syc-insight-buy-head {
    display: flex;
    justify-content: space-between;
    gap: .5rem;
}

.syc-insight-gain { color: var(--syc-primary); font-weight: 700; white-space: nowrap; }

/* The one buy's thin spot: "Hot · Work/Professional: 2 outfits now", above the piece. */
/* Your week: seven rows of a day and two small menus, fitting a 375px phone. */
.syc-your-week-days { width: 100%; border-collapse: separate; border-spacing: 0 .3rem; }
.syc-your-week-days th { font-size: .8rem; font-weight: 600; color: var(--syc-text-muted); }
.syc-your-week-days tbody th { width: 2.75rem; color: var(--syc-text); }
.syc-your-week-days td { padding-left: .35rem; }

/* Your uniforms: a season, then a line per piece -- what it needs, what is owned, and the verdict,
   which wraps under the numbers on a 375px phone rather than squeezing them. */
.syc-uniform + .syc-uniform { margin-top: .9rem; padding-top: .75rem; border-top: 1px dashed var(--syc-border); }
.syc-uniform-head { display: flex; flex-wrap: wrap; gap: .25rem .5rem; align-items: baseline; margin-bottom: .4rem; }
.syc-uniform-how { font-size: .8rem; color: var(--syc-text-muted); }
.syc-uniform-line {
    display: grid;
    grid-template-columns: minmax(6rem, 1fr) auto;
    gap: 0 .6rem;
    font-size: .9rem;
    margin-bottom: .45rem;
}
.syc-uniform-label { font-weight: 600; }
.syc-uniform-nums { font-variant-numeric: tabular-nums; text-align: right; }
.syc-uniform-verdict { grid-column: 1 / -1; font-size: .8rem; font-weight: 600; }
.syc-uniform-line.short .syc-uniform-verdict { color: var(--syc-accent, #EE5A3C); }
.syc-uniform-line.more .syc-uniform-verdict { color: var(--syc-primary); }
.syc-uniform-line.on-target .syc-uniform-verdict { color: var(--syc-success); }

/* A line's pieces: counted first, then the rest greyed with the reason. */
.syc-uniform-pieces { grid-column: 1 / -1; margin-top: .2rem; }
.syc-uniform-pieces > summary { font-size: .8rem; color: var(--syc-primary); cursor: pointer; }
.syc-uniform-piece {
    display: grid;
    grid-template-columns: 2.5rem 1fr auto;
    align-items: center;
    gap: .5rem;
    padding: .3rem 0;
    border-bottom: 1px solid var(--syc-border);
    font-size: .85rem;
}
.syc-uniform-piece img, .syc-uniform-piece-blank {
    width: 2.5rem; height: 2.5rem; object-fit: contain;
    border-radius: 6px; background: var(--syc-surface-alt, var(--syc-border));
}
.syc-uniform-piece-name { min-width: 0; overflow-wrap: anywhere; }
.syc-uniform-piece-name small { display: block; color: var(--syc-text-muted); }
.syc-uniform-piece.out img, .syc-uniform-piece.out .syc-uniform-piece-name { opacity: .55; }

/* Plans: a day's evening, under its daytime outfit. */
.syc-week-evening { margin-top: .75rem; padding-top: .6rem; border-top: 1px dashed var(--syc-border); }
.syc-week-evening-title { font-size: .85rem; font-weight: 700; margin: 0 0 .4rem; }

/* An item's dressiness, under its tags: five chips, the current one selected. */
.syc-read-dressiness { margin-top: .75rem; }
.syc-read-dressiness-label { margin: 0 0 .35rem; font-size: .9rem; font-weight: 600; }
.syc-read-dressiness-label .text-muted { font-weight: 400; }

/* Plans: Plan a trip and Plan an event side by side, above the 7 day plan. */
.syc-plan-starts { display: grid; grid-template-columns: 1fr 1fr; gap: .5rem; margin-bottom: 1rem; }
.syc-plan-starts .btn { display: flex; align-items: center; justify-content: center; white-space: nowrap; }

/* Plans: the 7 day plan's heading, under the buttons. */
.syc-week-title { font-size: 1.15rem; font-weight: 700; margin: 0 0 .5rem; }
/* The embedded plan's heading is its own fold button: the whole row, the title and a chevron. */
.syc-week-toggle {
    display: flex; align-items: center; justify-content: space-between; gap: .5rem;
    width: 100%; padding: .6rem .75rem;
    border: 1px solid var(--syc-border); border-radius: var(--syc-radius);
    background: var(--syc-surface); color: inherit; font: inherit; text-align: left;
}

/* Today's pop-up: the weather under its caption. */
.syc-today-modal-weather { font-size: .85rem; color: var(--syc-text); margin-top: .25rem; }

/* Today: a uniform day's line, and tonight's outfit under the day's. */
.syc-today-uniform { color: var(--syc-text-muted); margin-bottom: .5rem; }
.syc-today-tonight { margin-top: 1rem; padding-top: .75rem; border-top: 1px solid var(--syc-border); }
.syc-today-tonight-title { font-size: .9rem; font-weight: 700; margin: 0 0 .5rem; }

.syc-insight-buy-spot { font-size: .75rem; color: var(--syc-text-muted); margin-bottom: .1rem; }

/* What you can make: occasions down the side, weathers across. Four number columns and a name
   column fit a 375px phone; the name wraps rather than the numbers shrinking. */
.syc-insight-grid {
    width: 100%;
    border-collapse: separate;
    border-spacing: .3rem;
    margin: 0 -.3rem;
    table-layout: fixed;
}

.syc-insight-grid th {
    font-size: .8rem;
    font-weight: 600;
    text-align: center;
    vertical-align: middle;
}

.syc-insight-grid thead th { color: var(--syc-text-muted); font-weight: 500; }
.syc-insight-grid thead th:first-child { width: 34%; }
.syc-insight-grid-band { display: block; font-size: .7rem; }
.syc-insight-grid tbody th { text-align: left; line-height: 1.2; overflow-wrap: anywhere; }

.syc-insight-cell {
    width: 100%;
    min-height: 2.6rem;
    border: 1px solid var(--syc-border);
    border-radius: .5rem;
    background: var(--syc-surface-alt);
    color: var(--syc-text);
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.syc-insight-cell.thin,
.syc-insight-key.thin {
    background: color-mix(in srgb, var(--syc-accent, #EE5A3C) 18%, var(--syc-surface));
    border-color: var(--syc-accent, #EE5A3C);
}

.syc-insight-cell.selected { outline: 2px solid var(--syc-primary); outline-offset: 1px; }

.syc-insight-key {
    display: inline-block;
    width: .8rem;
    height: .8rem;
    border: 1px solid;
    border-radius: .2rem;
    vertical-align: -.1rem;
    margin-right: .25rem;
}

.syc-insight-cell-detail {
    margin-top: .5rem;
    padding: .55rem .7rem;
    border-radius: .5rem;
    background: var(--syc-surface-alt);
    font-size: .85rem;
}

.syc-insight-coats { display: flex; justify-content: space-between; margin: 0 0 .35rem; font-size: .85rem; }

/* Small garment cards: photograph, name, and the line about it. */
.syc-insight-items {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(6.5rem, 1fr));
    gap: .6rem;
}

.syc-insight-item {
    display: flex;
    flex-direction: column;
    gap: .2rem;
    color: inherit;
    text-decoration: none;
    min-width: 0;
}

.syc-insight-item img,
.syc-insight-item .syc-outfit-noimg {
    width: 100%;
    aspect-ratio: 1;
    object-fit: contain;
    border: 1px solid var(--syc-border);
    border-radius: var(--syc-radius);
    background: var(--syc-surface-alt);
}

.syc-insight-item-name { font-size: .78rem; line-height: 1.2; overflow-wrap: anywhere; }
.syc-insight-item-line { font-size: .72rem; line-height: 1.2; color: var(--syc-text-muted); }

.syc-swatch {
    display: inline-block;
    width: .75rem;
    height: .75rem;
    border-radius: 999px;
    border: 1px solid var(--syc-border);
}

/* ---- Closet type bands ---------------------------------------------------------------------
   Each clothing type on the closet screen has its own colour, as a solid band across its heading,
   and its subtypes sit on a pale wash of the same colour. Reported as "the closet page is bland".

   Two families only, the brand's own: Teal and Brick, in shades. Tops, Bottoms and Dresses set
   the tone, and a first palette that added an ochre, a green, a dusk blue, a vermilion and a gold
   for the rest was reported as "random and loud". So the rest are deeper or softer versions of
   those three, alternating teal and brick down the closet. Tops and Bottoms are the one pair of
   neighbours in the same family, told apart by depth -- they were liked as they were.

   Only on the bands. The garments themselves sit on white: a photograph seen through a tint is a
   photograph of a different colour, and colour is what people choose clothes by.

   The cool ones were five greys of one teal -- reported as "teal, the blues and the black all
   look like the same gray". So they spread across the cool side instead, from sea green to navy,
   and their subtypes sit on a clear pastel of their own hue (--syc-type-wash) rather than the
   type colour faded towards white, which for a dark teal is grey.

   Every band is a third less saturated than the brand shade it started from -- at full strength
   they were reported as "too bright, competing with the teal welcome and weather" above them.

   White text on every band, each at least 5:1. */
.syc-type-band { --syc-type: var(--syc-primary); --syc-type-ink: #FFFFFF; border-color: var(--syc-type); }
.syc-type-top         { --syc-type: #28454B; --syc-type-wash: #DAE9EC; }   /* Deep Teal, softened */
.syc-type-bottom      { --syc-type: #295E6A; --syc-type-wash: #DFEDF1; }   /* Teal, softened */
.syc-type-dress       { --syc-type: #984936; }   /* Brick, softened */
.syc-type-outerwear   { --syc-type: #2F445F; --syc-type-wash: #DFE7F1; }   /* Navy, softened */
.syc-type-shoes       { --syc-type: #7C4434; }   /* Deep brick, softened */
.syc-type-athletic    { --syc-type: #27665F; --syc-type-wash: #DFF1EF; }   /* Sea green, softened */
.syc-type-nightwear   { --syc-type: #6B3C2F; }   /* Oxblood, softened */
.syc-type-accessories { --syc-type: #3C5972; --syc-type-wash: #DFE9F1; }   /* Petrol blue, softened */
.syc-type-handbags    { --syc-type: #945544; }   /* Terracotta, softened */
.syc-type-jewelry     { --syc-type: #4A5F7F; --syc-type-wash: #E3E8F3; }   /* Slate blue, softened */

.syc-type-band > .syc-type-summary {
    /* A faint sheen, not a gradient anyone would name: 14% lighter along the top edge, back to the
       band's own colour by 65% of the way down -- 7% was too faint to see on a phone. The band looks
       lit rather than flat -- the cover's soft light circle, said more quietly. Same hue
       throughout, so the colour still tells the types apart; the text sits where it is
       the band's own colour, still 5:1. */
    background:
        linear-gradient(to bottom, color-mix(in srgb, var(--syc-type) 86%, #FFFFFF), var(--syc-type) 65%);
    color: var(--syc-type-ink);
    padding-block: 0.75rem;
    font-family: var(--syc-font-heading);
    font-size: 1.02rem;
}
.syc-type-band > .syc-type-summary::before { color: inherit; opacity: 0.8; }
.syc-type-band > .syc-type-summary .syc-type-count {
    color: inherit;
    background: color-mix(in srgb, var(--syc-type-ink) 16%, transparent);
    border-color: transparent;
    font-family: var(--syc-font-base);
}
.syc-type-icon { flex-shrink: 0; }

/* Subtypes: a pale wash of the type's colour with a solid rail, in place of the grey hairline. */
.syc-type-band .syc-subtype-group {
    margin: 0.6rem 0.6rem 0;
    padding: 0 0.6rem;
    border-left: 3px solid var(--syc-type);
    border-radius: 0 var(--syc-radius) var(--syc-radius) 0;
    background: var(--syc-type-wash, color-mix(in srgb, var(--syc-type) 9%, #FFFFFF));
}
.syc-type-band .syc-subtype-group:last-of-type { margin-bottom: 0.6rem; }
.syc-type-band .syc-subtype-summary {
    color: var(--syc-text);
    font-size: 0.9rem;
    padding: 0.45rem 0;
}
.syc-type-band .syc-subtype-summary .syc-type-count { background: #FFFFFF; }
.syc-type-band .syc-subtype-group .syc-card-grid {
    padding: 0 0 0.6rem;
}

/* One of the owner's own garments, standing for its subtype. */
.syc-subtype-cover {
    width: 34px;
    height: 34px;
    border-radius: 8px;
    object-fit: contain;   /* cut-outs: the whole garment, not its middle */
    background: #FFFFFF;
    border: 1px solid color-mix(in srgb, var(--syc-type, var(--syc-border)) 35%, #FFFFFF);
    flex-shrink: 0;
}

/* Three of the type's garments at the right end of its band, overlapping like a fanned hand of
   cards. Sized inside the band's own padding, so the band is no taller with them than without. */
.syc-type-strip {
    display: flex;
    margin-inline-start: auto;
    padding-inline-start: 0.5rem;
}
.syc-type-strip img {
    width: 30px;
    height: 30px;
    margin-block: -4px;
    border-radius: 7px;
    object-fit: contain;
    background: #FFFFFF;
    border: 2px solid var(--syc-type, var(--syc-border));
}
.syc-type-strip img + img { margin-inline-start: -9px; }
.syc-type-group[open] > .syc-type-summary .syc-type-strip { display: none; }

/* ---- Closet cover ---------------------------------------------------------------------------
   The greeting as a Deep Teal card with three of the owner's garments fanned beside it, like a
   hand of cards -- see ClosetCover. The Vermilion rule under it is the header's stripe. */
.syc-cover {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 1rem;
    border-radius: var(--syc-radius-lg);
    border-bottom: 3px solid var(--syc-accent);
    background: var(--syc-primary);
    color: #FFFFFF;
    overflow: hidden;
}
.syc-cover-words { flex: 1 1 auto; min-width: 0; }
.syc-cover-greeting {
    margin: 0;
    font-family: var(--syc-font-heading);
    font-size: 1.45rem;
    font-weight: 800;
    line-height: 1.15;
    letter-spacing: -0.01em;
    color: #FFFFFF;
}
.syc-cover-sub {
    margin: 0.3rem 0 0;
    font-size: 0.95rem;
    color: #FDE1D8;   /* Vermilion Tint, 7.8:1 on Deep Teal */
}
.syc-cover-caption {
    margin: 0.6rem 0 0;
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: #F7A491;   /* 4.9:1 on Deep Teal */
}
.syc-cover-photos {
    display: flex;
    flex-shrink: 0;
    padding-inline-end: 0.25rem;
}
.syc-cover-photo {
    width: 64px;
    height: 80px;
    padding: 4px;
    border: 0;
    border-radius: 10px;
    background: #FFFFFF;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.28);
    cursor: pointer;
}
.syc-cover-photo img { width: 100%; height: 100%; object-fit: contain; }
.syc-cover-photo + .syc-cover-photo { margin-inline-start: -18px; }
.syc-cover-photo:nth-child(1) { transform: rotate(-7deg); }
.syc-cover-photo:nth-child(2) { transform: translateY(-5px); z-index: 1; }
.syc-cover-photo:nth-child(3) { transform: rotate(7deg); }

/* The cover through the year (SeasonalLook). The card stays Deep Teal -- it is the brand, and the
   words are measured against it -- and what changes is the trim: a stripe under it in the month's
   three colours; the small caption, in the season's; and the month's two marks beside the name.
   The stripe is the bottom 6px of the background so it follows the card's rounded corners (a
   border-image would square them off), and a smooth gradient rather than three flat bands: at 4px
   the bands were reported as "almost invisible". Every caption colour is over 4.5:1 on Deep Teal. */
.syc-cover[class*="syc-season-"] {
    border-bottom: 0;
    padding-bottom: calc(1rem + 6px);
    background:
        linear-gradient(90deg, var(--syc-month-1), var(--syc-month-2) 50%, var(--syc-month-3)) bottom / 100% 6px no-repeat,
        var(--syc-primary);
}
.syc-cover-motif {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    margin-inline-start: 0.45rem;
    margin-inline-end: 0.3rem;
    font-size: 0.95rem;
    line-height: 1;
    vertical-align: -0.12em;
}
.syc-cover-caption .syc-cover-motif { margin-inline-start: 0; }
.syc-cover-motif svg { width: 0.95rem; height: 0.95rem; display: block; }

/* The month's stripe: what the month looks like outside, light to deep. */
.syc-month-1  { --syc-month-1: #E4F3F9; --syc-month-2: #A9D3E6; --syc-month-3: #6FA6C4; }   /* Snow, frost, ice */
.syc-month-2  { --syc-month-1: #F4B6C8; --syc-month-2: #E4F3F9; --syc-month-3: #A9D3E6; }   /* Valentine pink, snow */
.syc-month-3  { --syc-month-1: #CFE7F1; --syc-month-2: #B7DA9F; --syc-month-3: #8CC084; }   /* Thaw, first green */
.syc-month-4  { --syc-month-1: #A9D3E6; --syc-month-2: #F4B6C8; --syc-month-3: #8CC084; }   /* Showers, blossom, leaf */
.syc-month-5  { --syc-month-1: #F4B6C8; --syc-month-2: #F7E08A; --syc-month-3: #8CC084; }   /* Blossom, primrose, leaf */
.syc-month-6  { --syc-month-1: #F7E08A; --syc-month-2: #F2C14E; --syc-month-3: #E8893A; }   /* Sun */
.syc-month-7  { --syc-month-1: #F2C14E; --syc-month-2: #E8893A; --syc-month-3: #6FC3CF; }   /* Sun, sea */
.syc-month-8  { --syc-month-1: #F7D57E; --syc-month-2: #E8893A; --syc-month-3: #6FC3CF; }   /* Sand, sun, sea */
.syc-month-9  { --syc-month-1: #E9C46A; --syc-month-2: #E9A04B; --syc-month-3: #C8642F; }   /* Late summer into rust */
.syc-month-10 { --syc-month-1: #E9A04B; --syc-month-2: #C8642F; --syc-month-3: #9E3B4A; }   /* Ochre, rust, burgundy */
.syc-month-11 { --syc-month-1: #C8642F; --syc-month-2: #9E3B4A; --syc-month-3: #8A6A55; }   /* Rust, burgundy, bark */
.syc-month-12 { --syc-month-1: #E4F3F9; --syc-month-2: #A9D3E6; --syc-month-3: #C9485B; }   /* Snow, frost, berry */

.syc-season-autumn .syc-cover-caption { color: #E9B872; }   /* Ochre, 5.3:1 */
.syc-season-autumn .syc-cover-motif { color: #E9A04B; }

.syc-season-winter .syc-cover-caption { color: #CFE7F1; }   /* 7.5:1 */
.syc-season-winter .syc-cover-motif { color: #E4F3F9; }

.syc-season-spring .syc-cover-caption { color: #F4B6C8; }   /* Blossom, 5.7:1 */
.syc-season-spring .syc-cover-motif { color: #F4B6C8; }

.syc-season-summer .syc-cover-caption { color: #F7D57E; }   /* 6.8:1 */
.syc-season-summer .syc-cover-motif { color: #F7D57E; }

/* Outfit flat-lay -- an idea as one picture (OutfitFlatLay). What is worn on the body large on the
   left, top over bottom; the coat, shoes and bag smaller down the right. Each piece on a white tile
   so cut-outs and white-background photographs sit together; the panel is a pale teal wash, the
   same mix as the closet's subtype rows. */
.syc-flatlay {
    display: grid;
    grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
    gap: 0.6rem;
    height: 380px;
    padding: 0.75rem;
    background: color-mix(in srgb, var(--syc-primary) 9%, #FFFFFF);
}
.syc-flatlay-single { grid-template-columns: minmax(0, 1fr); }
.syc-flatlay-main,
.syc-flatlay-side {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    min-height: 0;
}
.syc-flatlay-piece {
    flex: 1 1 0;
    min-height: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0.35rem;
    background: #FFFFFF;
    border-radius: var(--syc-radius);
    box-shadow: 0 2px 6px rgba(20, 38, 43, 0.10);
}
/* What goes with the outfit is never bigger than a third of the picture: a single pair of shoes
   beside a dress filled the whole column and outweighed the dress. Several shrink to fit. */
.syc-flatlay-side { justify-content: center; }
.syc-flatlay-side .syc-flatlay-piece { flex: 0 1 calc((100% - 1.2rem) / 3); }
.syc-flatlay-piece img { width: 100%; height: 100%; object-fit: contain; display: block; }
.syc-flatlay-noimg { color: var(--syc-text-light); font-size: 1.5rem; }
.syc-flatlay-piece-tappable { cursor: pointer; transition: transform var(--syc-transition), box-shadow var(--syc-transition); }
.syc-flatlay-piece-tappable:hover { transform: translateY(-2px); box-shadow: 0 6px 14px rgba(20, 38, 43, 0.16); }
.syc-flatlay-piece-tappable:focus-visible { outline: 2px solid var(--syc-primary); outline-offset: 2px; }
/* Taller than it was (280, and 240 on a phone): "the pictures are a little too small to understand
   at a glance". A phone screen still shows the whole card, heading to buttons. */
@media (max-width: 400px) { .syc-flatlay { height: 340px; } }

/* An idea reads top to bottom: the vermilion rule, what it is for, the outfit, the buttons. */
.syc-idea-card { border-top: 4px solid var(--syc-accent); }

/* With no occasion chosen, the ideas come in groups (GetIdeaMixQuery), each under a heading:
   the occasion, a Today pill on the one today is for, and a muted line where one is needed. */
.syc-idea-group-head { margin: 1.25rem 0 0.6rem; }
.syc-idea-group-title {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    margin: 0;
    font-family: var(--syc-font-heading);
    font-size: 1.1rem;
    font-weight: 700;
    color: var(--syc-primary);
}
.syc-idea-group-today {
    font-family: var(--syc-font-base);
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    padding: 0.15rem 0.5rem;
    border-radius: 999px;
    background: #FDE1D8;   /* Vermilion Tint */
    color: #8B2E18;
}
.syc-idea-group-note { margin: 0.15rem 0 0; font-size: 0.85rem; color: var(--syc-text-muted); }

/* The quick check (QuickCheck): a progress bar, then one garment -- a large photo and three rows of
   chips. The photo is the garment's own screen as a link, for the one that needs a closer look. */
.syc-quick-progress { margin-bottom: 0.9rem; }
.syc-quick-progress-text { font-size: 0.9rem; margin-bottom: 0.35rem; }
.syc-quick-bar { height: 8px; border-radius: 999px; background: color-mix(in srgb, var(--syc-primary) 12%, #FFFFFF); overflow: hidden; }
.syc-quick-bar-fill { height: 100%; background: var(--syc-accent); border-radius: inherit; transition: width 0.3s ease; }
/* The photo and name stick under the bar while the questions scroll beneath them. The card is
   syc-card-form, which does not clip, because a clipping ancestor switches sticky off. */
.syc-quick-head {
    position: sticky;
    top: var(--syc-sticky-top, 0px);
    z-index: 5;
    background: var(--syc-surface);
    border-radius: var(--syc-radius-lg) var(--syc-radius-lg) 0 0;
    box-shadow: 0 6px 8px -8px rgba(20, 38, 43, 0.25);
}
/* Pinned with the photo, so it is one line: a long name is cut short rather than pushing the
   questions down. */
.syc-quick-head .syc-quick-progress { margin: 0; padding: 0.6rem 1rem 0.5rem; }
.syc-quick-title { padding: 0.5rem 1rem 0; }
.syc-quick-head .syc-quick-name,
.syc-quick-head .syc-quick-shelf { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.syc-quick-head .syc-quick-shelf { margin-bottom: 0.4rem; }
.syc-quick-head .syc-quick-saved { border-radius: 0; }
.syc-quick-question:focus { outline: none; }
.syc-quick-question:focus-visible { outline: 2px solid var(--syc-accent); outline-offset: 2px; }
.syc-quick-saved {
    margin: 0;
    padding: 0.4rem 1rem;
    border-radius: var(--syc-radius-lg) var(--syc-radius-lg) 0 0;
    background: color-mix(in srgb, var(--syc-success) 14%, var(--syc-surface));
    color: var(--syc-success);
    font-size: 0.85rem;
}
/* Each garment arrives from the right, so the change from one to the next is seen. */
.syc-quick-card { animation: syc-quick-in 0.3s ease-out; }
@keyframes syc-quick-in {
    from { opacity: 0; transform: translateX(24px); }
    to { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) { .syc-quick-card { animation: none; } }
.syc-quick-photo {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    /* Shorter than it was, now that it stays on screen: the questions need the room. */
    height: 160px;
    padding: 0.5rem;
    background: color-mix(in srgb, var(--syc-primary) 6%, #FFFFFF);
    border: 0;
    border-bottom: 1px solid var(--syc-border);
}
/* A button that enlarges the photo -- see PhotoLightbox. */
button.syc-quick-photo { cursor: zoom-in; }
.syc-quick-photo img { max-width: 100%; max-height: 100%; object-fit: contain; border-radius: var(--syc-radius); }
.syc-quick-name { margin: 0; font-family: var(--syc-font-heading); font-weight: 700; font-size: 1.1rem; }
.syc-quick-shelf { margin: 0.1rem 0 0.6rem; font-size: 0.85rem; color: var(--syc-text-muted); }
.syc-quick-question { margin: 0.75rem 0 0.35rem; font-size: 0.9rem; font-weight: 600; }
.syc-quick-guess { margin-left: 0.35rem; font-weight: 400; color: var(--syc-text-muted, #6c757d); font-size: 0.8rem; }
.syc-quick-done-icon { font-size: 2rem; color: var(--syc-accent); }

/* One piece of today's outfit, asked about straight after Wear this (TodayCard). */
.syc-after-wear {
    margin-top: 0.75rem;
    padding: 0.75rem;
    border-radius: var(--syc-radius);
    background: color-mix(in srgb, var(--syc-primary) 6%, #FFFFFF);
}
.syc-after-wear-title { margin: 0 0 0.35rem; font-size: 0.9rem; }
.syc-after-wear-thanks { margin: 0.75rem 0 0; font-size: 0.9rem; color: var(--syc-primary); }
.syc-idea-card > .syc-outfit-line { padding: 0.7rem 1rem 0.55rem; }

/* The heading over the picture: the look's name or occasion, then the weather. */
.syc-outfit-line { display: flex; flex-wrap: wrap; align-items: baseline; column-gap: 0.5rem; }
.syc-outfit-line .syc-outfit-name {
    font-family: var(--syc-font-heading);
    font-size: 1.1rem;
    margin-bottom: 0;
}
.syc-outfit-facts { font-size: 0.85rem; color: var(--syc-text-muted); }

/* Plans -- the photographs across the top of a trip or event card (TripCover picks them). The
   same white tiles on a wash as an outfit idea: teal for a trip, the vermilion tint for an event,
   so the two kinds of plan differ at a glance as well as by their icon. */
.syc-plan-photos {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    /* One row the height of the panel. Without it the row was as tall as the tallest photograph,
       so a long skirt stood out of the panel and over the plan's name and buttons. */
    grid-template-rows: minmax(0, 1fr);
    gap: 0.5rem;
    height: 112px;
    overflow: hidden;
    padding: 0.6rem 0.75rem;
    background: color-mix(in srgb, var(--syc-primary) 9%, #FFFFFF);
    border-bottom: 3px solid var(--syc-primary);
    cursor: pointer;
}
.syc-plan-photos-event {
    background: var(--syc-accent-subtle);
    border-bottom-color: var(--syc-accent-dark);
}
.syc-plan-photo {
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 0;
    min-height: 0;
    overflow: hidden;
    padding: 0.25rem;
    background: #FFFFFF;
    border-radius: var(--syc-radius);
    box-shadow: 0 2px 6px rgba(20, 38, 43, 0.10);
}
.syc-plan-photo img { width: 100%; height: 100%; max-height: 100%; object-fit: contain; display: block; }

/* Start from a piece (StartFromAPiece) -- choose the garment to build an outfit around. The link
   into it is the same on Today's outfit and on Ideas: one line, a pale teal wash, an arrow. */
.syc-start-piece {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    margin-top: 0.75rem;
    padding: 0.6rem 0.8rem;
    border: 1px solid color-mix(in srgb, var(--syc-primary) 18%, transparent);
    border-radius: var(--syc-radius);
    background: color-mix(in srgb, var(--syc-primary) 6%, var(--syc-surface));
    color: var(--syc-primary);
    font-size: 0.9rem;
    text-decoration: none;
}
.syc-start-piece:hover { background: color-mix(in srgb, var(--syc-primary) 10%, var(--syc-surface)); color: var(--syc-primary); }
.syc-start-piece .bi-arrow-right { flex-shrink: 0; }

.syc-piece-intro { margin: 0 0 1rem; color: var(--syc-text-muted); }
.syc-piece-section { margin-bottom: 1.25rem; }
.syc-piece-heading {
    margin: 0 0 0.5rem;
    font-family: var(--syc-font-heading);
    font-size: 1rem;
    font-weight: 700;
}
/* The two short rows scroll sideways, so the categories stay near the top of the phone. */
.syc-piece-row {
    display: flex;
    gap: 0.6rem;
    overflow-x: auto;
    padding-bottom: 0.35rem;
    scroll-snap-type: x proximity;
}
.syc-piece-row .syc-piece { flex: 0 0 96px; scroll-snap-align: start; }
.syc-piece-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
    gap: 0.6rem;
}
.syc-piece {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    min-width: 0;
    padding: 0;
    border: 0;
    background: none;
    text-align: start;
    color: var(--syc-text);
    cursor: pointer;
}
.syc-piece-photo {
    display: flex;
    align-items: center;
    justify-content: center;
    aspect-ratio: 4 / 5;
    padding: 6px;
    border: 1px solid var(--syc-border);
    border-radius: var(--syc-radius);
    overflow: hidden;
}
.syc-piece-photo img { width: 100%; height: 100%; object-fit: contain; }
.syc-piece:hover .syc-piece-photo,
.syc-piece:focus-visible .syc-piece-photo { border-color: var(--syc-primary); box-shadow: 0 0 0 2px color-mix(in srgb, var(--syc-primary) 25%, transparent); }
.syc-piece-name {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    font-size: 0.78rem;
    line-height: 1.25;
}

/* Sample closets: Add starter list, Cut out Unsplash photos and Add item, full width and stacked on a phone. */
.syc-sample-actions { display: grid; gap: .5rem; }
@media (min-width: 768px) {
    .syc-sample-actions { grid-auto-flow: column; grid-auto-columns: max-content; justify-content: end; }
}

/* "Photo by X on Unsplash" under a photo from Unsplash -- see PhotoCredit.razor. */
.syc-photo-credit {
    margin-top: 0.35rem;
    text-align: center;
}

.syc-photo-credit a {
    color: inherit;
    text-decoration: underline;
}
