﻿/* 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-accent);
    border-color: var(--syc-accent);
    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;
    overflow: hidden;
}
.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);
}
.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: #EEF3F7;
    border-color: #C3D4E0;
    color: #2E4557;
    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); }

/* 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);
    color: var(--syc-text);
}

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

/* 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;
    z-index: 1080;
    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. */
.syc-tabbar {
    position: fixed;
    left: .75rem;
    right: .75rem;
    bottom: calc(.6rem + env(safe-area-inset-bottom, 0px));
    z-index: 1035;
    display: flex;
    background: var(--syc-surface);
    border: 1px solid var(--syc-border);
    border-radius: 999px;

    /* Deeper and softer than a bar sitting on the edge: what sells a floating thing is the shadow
       under it, and a 2px line does not say "above" to anybody. */
    box-shadow: 0 6px 20px rgba(0, 0, 0, .16), 0 1px 3px rgba(0, 0, 0, .08);

    /* The pill clips its own corners, so a lit tab's background cannot escape them. */
    overflow: hidden;
}

.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;
    z-index: 1092;
    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;
}

.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. */
.syc-sheet-backdrop {
    position: fixed;
    inset: 0;
    z-index: 1091;
    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; }

/* 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);
}

/* ── 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, #d9d2c7);
    border-left: 3px solid var(--syc-accent, #8a7a63);
    border-radius: .5rem;
    background: var(--syc-surface-muted, #f6f2ec);
    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. */
.syc-sort { margin-left: auto; }
.syc-sort .form-select { width: auto; min-width: 9.5rem; }
.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. */
.syc-closet-filter {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: .5rem;
    margin-block: .35rem .6rem;
    font-size: .82rem;
    color: var(--syc-text-muted);
}

/* 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;
}

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

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

/* Above the scrim, which it was not.

   The backdrop sits at 1091 and this sat at 1060, so the enlarged photograph was being painted
   under a sheet of 45% black. It read as though the large image were a darker copy of the
   thumbnail -- the one explanation nobody would arrive at, because the two are the same file. */
.syc-look {
    position: fixed;
    inset-block-start: 50%;
    inset-inline-start: 50%;
    transform: translate(-50%, -50%);
    z-index: 1092;
    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; }

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

/* 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, #6b7780);
    font-size: .9rem;
    border-top: 1px solid var(--syc-border, #e3e7ea);
    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 ────────────────────────────────────────────── */

/* A band of its own, white, with nothing else on the line.

   It scrolls away with the page rather than sticking to the top: it is a welcome, not a control,
   and a welcome that follows somebody down two hundred garments stops being one. The bar that
   matters -- the screen name and the way out -- is the sticky one below it. */
.syc-greeting-band {
    background: #fff;
    margin: -1rem -1rem 0;
    padding: 1.25rem 1rem .75rem;
}

.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; }

/* 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;
    gap: .3rem;
}

.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;
    font-size: .8rem;
    font-weight: 500;
    line-height: 1.2;
    color: #fff;
    opacity: .85;
    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-primary-dark, var(--syc-primary));
}

.syc-tab.active .bi {
    background: var(--syc-accent, #E8A598);
    color: #fff;
    border-radius: 999px;
    padding: .2rem .9rem;
    box-shadow: 0 2px 6px rgba(200, 128, 111, .35);
}

.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.
 
       The closet is the only screen with something above its bar -- the greeting -- so it is the
       only one where the bar was never pulled up to cover the notch. Scrolling the greeting away
       then stuck the bar at zero and put the hanger, Select and the hamburger behind the status
       bar. Sticking it an inset lower leaves the bar whole.
 
       That leaves the strip above it, which the page would otherwise scroll through. The greeting
       is white, so the strip is white: at rest it is indistinguishable from the greeting behind it,
       and once the greeting has gone it reads as the ground the clock sits on. Fixed, and above
       the bar, so nothing passes in front of it. */
    .syc-screen-title:not(:first-child) {
        top: env(safe-area-inset-top, 0px);
    }

    .syc-greeting-band::before {
        content: "";
        position: fixed;
        inset-block-start: 0;
        inset-inline: 0;
        height: env(safe-area-inset-top, 0px);
        background: #fff;
        z-index: 1041;
        pointer-events: none;
    }

    /* The same treatment, so the white reaches behind the clock instead of leaving a strip of
       page above it.
 
       This is where the greeting was landing on the status bar, and the fault was arithmetic. The
       band pulled up by 1rem + the inset while the page only had 1rem of padding to give, so it
       started an inset ABOVE the viewport -- and the inset added to its padding then only brought
       the text back to where it would have been anyway. The two cancelled. With the page now
       holding 1rem + the inset, pulling up by the same figure lands the band exactly at the top
       edge, and the padding below is clear space rather than a correction. */
    .syc-greeting-band {
        margin-top: calc(-1rem - env(safe-area-inset-top, 0px));
        padding-top: calc(1.25rem + 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, #5A7A90); 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, #E8A598); 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, #E8A598); 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, #5A7A90);
    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, #E8A598);
    border-radius: 0 var(--syc-radius) var(--syc-radius) 0;
    background: var(--syc-accent-subtle, #FBF0EE);
    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, #C8806F);
}

/* 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; }

.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;

    background: var(--syc-surface);
    border-block-start: 1px solid var(--syc-border);
    box-shadow: 0 -6px 20px rgba(0, 0, 0, .10);
}

@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;

    display: flex;
    align-items: center;
    justify-content: center;
    gap: .4rem;

    padding: .5rem .6rem;
    border: 1px solid transparent;
    border-radius: 999px;
    background: none;
    color: var(--syc-text);
    font-size: .85rem;
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.syc-trip-drawer-tab.on {
    background: var(--syc-accent-subtle);
    border-color: var(--syc-accent-light);
    color: var(--syc-accent-dark);
}

/* Opened, it is a sheet rather than a page: capped, and scrolling inside itself, so opening it
   never pushes the day out from under the heading that names it. */
.syc-trip-drawer-panel {
    max-height: min(60vh, 28rem);
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    padding: 0 .75rem .75rem;
    border-block-start: 1px solid var(--syc-border);
}


/* ------------------------------------------------------------- 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;
    font-size: .85rem;
    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 {
    bottom: env(safe-area-inset-bottom, 0px);
}
