@layer components {
/* File-upload card. Visual state is driven by the psw-upload--{state}
   modifier set by the partial. */

.psw-upload {
    --psw-up-accent: var(--theme-primary, var(--theme-primary-default));
    display: flex;
    flex-direction: column;
    background: var(--color-white);
    border-radius: var(--radius-lg);
    box-sizing: border-box;
    /* Positioning box for the expiration popover (see the picker rule below). */
    position: relative;
}

/* Project focus from the SR-only input onto the visible card. */
.psw-upload:has(.psw-upload__input:focus-visible) {
    outline: 3px solid var(--psw-up-accent);
    outline-offset: 2px;
    border-radius: var(--radius-lg);
}

/* Dropzone variants — shared dashed border, dash 5 / gap 5 per Figma.
   `border: dashed` gives no dash control, so the ring is an ::after overlay:
   an inline SVG (stroke-dasharray 5 5, rx matching the card's --radius-lg)
   used as a mask over a background-colored fill. Unlike the psw-document
   dropzone's baked-hex SVG background-image, the mask keeps the color in
   CSS, which --dragging needs for its runtime theme accent. The old 1px
   border is folded into the padding (25 + 1) so content geometry is
   unchanged; the 2px stroke sits centered on the card edge, so its visible
   inner half is the same 1px line as before. */
.psw-upload--enabled,
.psw-upload--error,
.psw-upload--dragging,
.psw-upload--uploading {
    --psw-up-dash: var(--color-gray-500);
    position: relative;
    padding: 26px;
    min-height: 210px;
    box-sizing: border-box;
}
.psw-upload--enabled::after,
.psw-upload--error::after,
.psw-upload--dragging::after,
.psw-upload--uploading::after {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    background: var(--psw-up-dash);
    -webkit-mask: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='100%25' height='100%25'%3e%3crect width='100%25' height='100%25' fill='none' stroke='%23000' stroke-width='2' stroke-dasharray='5 5' rx='8' ry='8'/%3e%3c/svg%3e");
            mask: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='100%25' height='100%25'%3e%3crect width='100%25' height='100%25' fill='none' stroke='%23000' stroke-width='2' stroke-dasharray='5 5' rx='8' ry='8'/%3e%3c/svg%3e");
}
.psw-upload--error    { --psw-up-dash: var(--color-danger-400); }
.psw-upload--dragging {
    background: var(--color-info-100);
    --psw-up-dash: var(--psw-up-accent);
}

/* Hit area fills the entire dropzone so any click anywhere in the card
   opens the picker. */
.psw-upload__hit {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--space-4);
    cursor: pointer;
    flex: 1;
    align-self: stretch;
}
.psw-upload__hit--center {
    justify-content: center;
}

.psw-upload--uploading .psw-upload__hit { cursor: default; }
.psw-upload--disabled  .psw-upload__hit { cursor: not-allowed; }
.psw-upload--disabled                   { opacity: 0.55; }

.psw-upload__icon-circle {
    width: 48px;
    height: 48px;
    border-radius: var(--radius-max);
    /* Static entity-avatar treatment (not themed): Gray 200 bg + Gray 600 icon. */
    background: var(--color-gray-200);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--color-gray-600);
    flex-shrink: 0;
}
.psw-upload__icon-circle .psw-icon {
    color: currentColor;
}

.psw-upload__text {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    min-width: 0;
}
.psw-upload__text--center {
    align-items: center;
    text-align: center;
}

.psw-upload__title {
    margin: 0;
    font-family: var(--font-sans);
    font-weight: var(--font-weight-bold);
    font-size: var(--text-label-md);
    line-height: var(--text-label-md--line-height);
    color: var(--color-content-high);
}
.psw-upload__subtitle {
    margin: 0;
    font-family: var(--font-sans);
    font-weight: var(--font-weight-regular);
    font-size: var(--text-paragraph-sm);
    line-height: var(--text-paragraph-sm--line-height);
    color: var(--color-content-medium);
}

@media (hover: none) and (pointer: coarse) {
    /* Coarse-pointer devices use the compact icon + button treatment. Apply
       the u-sr-only treatment to both empty states so errors do not shift the
       card, while label copy remains available to assistive technology. */
    .psw-upload--enabled .psw-upload__text,
    .psw-upload--error .psw-upload__text {
        position: absolute;
        width: 1px;
        height: 1px;
        padding: 0;
        margin: -1px;
        overflow: hidden;
        clip: rect(0, 0, 0, 0);
        white-space: nowrap;
        border: 0;
    }
}

.psw-upload__btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: 36px;
    min-width: 60px;
    padding: 10px 12px;
    border: var(--border-width-sm, 1px) solid var(--color-gray-300);
    border-radius: var(--radius-lg);
    background: var(--color-white);
    color: var(--psw-up-accent);
    font-family: var(--font-sans);
    font-weight: var(--font-weight-bold);
    font-size: var(--text-label-sm);
    line-height: var(--text-label-sm--line-height);
    cursor: pointer;
    user-select: none;
    transition: background-color 120ms ease, box-shadow 120ms ease;
}
.psw-upload__btn:hover {
    background: var(--color-gray-100);
}
.psw-upload__btn--link {
    height: auto;
    min-width: 0;
    padding: 0;
    border: 0;
    background: transparent;
    text-decoration: underline;
    text-underline-offset: 2px;
}
.psw-upload__btn--link:hover { background: transparent; }

.psw-upload__callout {
    margin: 0;
    font-family: var(--font-sans);
    font-weight: var(--font-weight-bold);
    font-size: var(--text-label-md);
    line-height: var(--text-label-md--line-height);
    color: var(--psw-up-accent);
    text-align: center;
}

.psw-upload__uploading-label {
    margin: 0;
    font-family: var(--font-sans);
    font-weight: var(--font-weight-bold);
    font-size: var(--text-label-md);
    line-height: var(--text-label-md--line-height);
    color: var(--color-content-high);
}

/* Indeterminate spinner — 48px ring, gray track + accent arc. */
.psw-upload__spinner {
    width: 48px;
    height: 48px;
    border-radius: var(--radius-max);
    background:
        conic-gradient(var(--psw-up-accent) 25%, transparent 0) border-box,
        var(--color-gray-200) padding-box;
    -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 4px), #000 calc(100% - 3px));
            mask: radial-gradient(farthest-side, transparent calc(100% - 4px), #000 calc(100% - 3px));
    animation: psw-upload-spin 900ms linear infinite;
    flex-shrink: 0;
}
@keyframes psw-upload-spin {
    to { transform: rotate(360deg); }
}
@media (prefers-reduced-motion: reduce) {
    .psw-upload__spinner { animation: none; }
}

/* Uploaded — doc layout: vertical stack with divider. */
.psw-upload--uploaded:not(.psw-upload--image) {
    background: var(--color-gray-100);
    border: var(--border-width-sm, 1px) solid var(--color-gray-300);
    padding: var(--space-4);
    gap: var(--space-4);
}

.psw-upload__doc-top {
    display: flex;
    align-items: center;
    gap: var(--space-4);
}

.psw-upload__doc-icon {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 48px;
    height: 48px;
    border-radius: var(--radius-max);
    /* Darker themed treatment: bg-surface (Gray 600) circle + white glyph. */
    background: var(--color-bg-surface, var(--color-gray-600));
    color: var(--color-white, #ffffff);
}
.psw-upload__doc-icon .psw-icon {
    color: currentColor;
}

.psw-upload__doc-top .psw-upload__text { flex: 1 0 0; min-width: 0; }

/* Trash remove button on the uploaded card (Figma 977:110221) — the shared
   icon_button in its circular tertiary skin (borderless on the card's white
   fill), which brings the hover/pressed washes, :focus-visible ring,
   touch-action and disabled handling with it. Two things it can't express as
   props: the glyph is the card's gray rather than the themed link color, and
   the hit area is the doc icon's 48px rather than the 36px that comes with
   the sm size the 20px trash needs. psw-upload.js wires the click to clear
   the field and restore the empty dropzone. */
.psw-upload .psw-upload__remove {
    width: 48px;
    height: 48px;
    color: var(--color-content-medium);
}

.psw-upload__divider {
    height: 1px;
    background: var(--color-gray-300);
}
.psw-upload__divider--short {
    width: 32px;
}

.psw-upload__inline-row {
    display: flex;
    align-items: center;
    gap: var(--space-2);
}

.psw-upload__label {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    color: var(--color-content-medium);
    font-family: var(--font-sans);
    font-weight: var(--font-weight-regular);
    font-size: var(--text-paragraph-sm);
    line-height: var(--text-paragraph-sm--line-height);
}
.psw-upload__check {
    color: var(--color-success-500);
    display: inline-flex;
    align-items: center;
}
.psw-upload__check .psw-icon {
    color: currentColor;
}

/* Uploaded — image layout: thumb | text | chevron. */
.psw-upload--image {
    background: transparent;
    border: 0;
    padding: 0;
}

.psw-upload__image-row {
    display: flex;
    align-items: center;
    gap: var(--space-4);
}

.psw-upload__thumb {
    flex-shrink: 0;
    width: 109px;
    height: 109px;
    border-radius: var(--radius-lg);
    object-fit: cover;
}

.psw-upload__image-row .psw-upload__text {
    flex: 1 0 0;
    min-width: 0;
    gap: var(--space-3);
}

/* In-card expiration row (_upload_expiration.html) — hidden until a file
   exists, then either the "Add expiration date" trigger or the icon +
   "Expires on …" + Edit row. The [hidden] attrs carry the state; every
   flex rule below re-hides on them (the UA rule alone would lose). */
.psw-upload__expiration {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
    min-width: 0;
}
.psw-upload__expiration[hidden] { display: none; }

/* Static so the 320px popover anchors to the card (position: relative above)
   rather than this wrapper — inside the image card's narrow text column it
   would clip off the viewport edge. The doubled selector outranks
   psw-date-picker.css's `.psw-date-picker { position: relative }`. */
.psw-upload .psw-upload__expiration-picker {
    display: flex;
    align-items: center;
    min-width: 0;
    position: static;
}

/* Bordered-button skin for the add affordance, matching the document
   widget's (psw-document.css .psw-document__upload-expiration-link). */
.psw-upload__expiration-add {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: 32px;
    padding: 6px 12px;
    border: 1px solid var(--color-gray-300, #E2E2E2);
    border-radius: 8px;
    background: var(--color-white);
    color: var(--theme-primary, var(--theme-primary-default));
    font-family: var(--font-sans);
    font-size: var(--text-label-sm);
    line-height: var(--text-label-sm--line-height);
    font-weight: var(--font-weight-bold);
    cursor: pointer;
}
.psw-upload__expiration-add[hidden] { display: none; }
.psw-upload__expiration-add:hover {
    background-image: linear-gradient(rgba(15, 15, 15, 0.04), rgba(15, 15, 15, 0.04));
}
.psw-upload__expiration-add:active,
.psw-date-picker--open > .psw-upload__expiration-add {
    background-image: linear-gradient(rgba(15, 15, 15, 0.08), rgba(15, 15, 15, 0.08));
}

.psw-upload__expiration-info {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex: 1 1 auto;
    min-width: 0;
}
.psw-upload__expiration-info[hidden] { display: none; }

.psw-upload__expiration-icon {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    color: var(--color-success-500);
}
.psw-upload__expiration-icon[hidden] { display: none; }
.psw-upload__expiration-icon .psw-icon {
    color: currentColor;
    width: 20px;
    height: 20px;
}
/* Yellow expiring-soon treatment (within 30 days). */
.psw-upload__expiration-icon--soon {
    color: var(--color-warning-400);
}

.psw-upload__expiration-text {
    flex: 1 1 auto;
    min-width: 0;
    color: var(--color-content-medium);
    font-family: var(--font-sans);
    font-size: var(--text-paragraph-sm);
    font-weight: var(--font-weight-regular);
    line-height: var(--text-paragraph-sm--line-height);
}

/* Underlined themed text link, matching the document widget's Edit. */
.psw-upload__expiration-edit {
    flex: 0 0 auto;
    padding: 0;
    border: 0;
    background: none;
    color: var(--theme-primary, var(--theme-primary-default));
    text-decoration: underline;
    font-family: var(--font-sans);
    font-weight: var(--font-weight-bold);
    font-size: var(--text-label-sm);
    line-height: var(--text-label-sm--line-height);
    cursor: pointer;
}

.psw-upload__expiration-add:focus-visible,
.psw-upload__expiration-edit:focus-visible {
    outline: 3px solid var(--theme-primary, var(--theme-primary-default));
    outline-offset: 2px;
}
}
