/**
 * Hoqmail — Components
 *
 * Self-contained, reusable pieces. Each block owns its own class namespace so
 * that adding a component can never change how an existing one renders.
 */

/* -------------------------------------------------------------------
   Card
   ------------------------------------------------------------------- */
.card {
    background-color: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-offset);
}

.card--brand {
    box-shadow: var(--shadow-offset-brand);
}

.card--flush {
    overflow: hidden;
}

.card__header {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-4) var(--space-5);
    border-bottom: 1px solid var(--color-border);
}

.card__body {
    padding: var(--space-5);
}

.card__body--tight {
    padding: var(--space-3) var(--space-5);
}

/* -------------------------------------------------------------------
   Button
   ------------------------------------------------------------------- */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    padding: 0.6rem 1.1rem;
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    background-color: var(--color-action);
    color: var(--color-action-contrast);
    font-size: var(--fs-body-3);
    font-weight: var(--fw-medium);
    line-height: 1.2;
    text-align: center;
    white-space: nowrap;
    cursor: pointer;
    transition: background-color var(--transition-fast),
                border-color var(--transition-fast),
                color var(--transition-fast);
}

.btn:hover {
    background-color: var(--color-action-hover);
    color: var(--color-action-contrast);
}

.btn--ghost {
    background-color: transparent;
    border-color: var(--color-border);
    color: var(--color-text);
}

.btn--ghost:hover {
    background-color: var(--color-surface-alt);
    color: var(--color-text-strong);
}

.btn--positive {
    background-color: var(--color-positive);
}

.btn--positive:hover {
    background-color: var(--color-positive-hover);
}

/*
 * Outlined, after the Boron theme's wishlist button: the red is stated by the
 * border and the label, not by a filled block. A destructive action should be
 * findable without shouting over the page, and filling only on hover means the
 * button announces itself at the moment it is about to be pressed.
 */
.btn--danger {
    border-color: var(--color-danger);
    color: var(--color-danger);
}

.btn--danger:hover {
    background-color: var(--color-danger-fill);
    border-color: var(--color-danger-fill);
    color: var(--color-danger-on-fill);
}

.btn--sm {
    padding: 0.4rem 0.8rem;
    font-size: var(--fs-caption);
}

.btn--block {
    width: 100%;
}

/* -------------------------------------------------------------------
   Form
   ------------------------------------------------------------------- */
.field + .field {
    margin-top: var(--space-4);
}

.field__label {
    display: block;
    margin-bottom: var(--space-2);
    font-size: var(--fs-caption);
    font-weight: var(--fw-medium);
    color: var(--color-text);
}

.input {
    display: block;
    width: 100%;
    padding: 0.6rem 0.85rem;
    background-color: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    color: var(--color-text-strong);
    font-size: var(--fs-body-3);
    transition: border-color var(--transition-fast);
}

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

.input:hover {
    border-color: var(--color-text-muted);
}

.input[readonly] {
    background-color: var(--color-surface-alt);
    color: var(--color-text-muted);
    cursor: default;
}

/* Search field: icon sits inside the control, never as a separate box. */
.search {
    display: flex;
    gap: var(--space-2);
}

.search__control {
    position: relative;
    flex: 1 1 auto;
}

.search__icon {
    position: absolute;
    top: 50%;
    left: 0.75rem;
    transform: translateY(-50%);
    color: var(--color-text-muted);
    pointer-events: none;
}

.search__control .input {
    padding-left: 2.5rem;
}

/* -------------------------------------------------------------------
   Avatar
   ------------------------------------------------------------------- */
.avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    border-radius: var(--radius-pill);
    background-color: var(--color-brand-tint);
    color: var(--color-brand-ink);
    font-size: var(--fs-caption);
    font-weight: var(--fw-semibold);
    text-transform: uppercase;
    flex-shrink: 0;
}

.avatar--lg {
    width: 2.75rem;
    height: 2.75rem;
    font-size: var(--fs-body-3);
}

/* -------------------------------------------------------------------
   Badge and chip
   ------------------------------------------------------------------- */
.badge {
    display: inline-flex;
    align-items: center;
    padding: 0.1rem 0.5rem;
    border-radius: var(--radius-pill);
    background-color: var(--color-surface-alt);
    color: var(--color-text-muted);
    font-size: var(--fs-caption);
    font-weight: var(--fw-medium);
}

.chip {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    padding: 0.15rem 0.6rem;
    border-radius: var(--radius-pill);
    background-color: var(--color-brand-tint);
    color: var(--color-brand-ink);
    font-size: var(--fs-caption);
    font-weight: var(--fw-medium);
}

/* -------------------------------------------------------------------
   Alert
   ------------------------------------------------------------------- */
.alert {
    display: flex;
    align-items: flex-start;
    gap: var(--space-3);
    padding: var(--space-4);
    border-radius: var(--radius-md);
    font-size: var(--fs-body-3);
}

.alert--danger {
    background-color: var(--color-danger-bg);
    color: var(--color-danger);
}

.alert__detail {
    margin-top: var(--space-1);
    font-size: var(--fs-caption);
    opacity: 0.85;
    word-break: break-word;
}

/* -------------------------------------------------------------------
   Dropdown

   Built on <details>, so opening and closing is the browser's job and
   works with scripting disabled. Only the appearance is defined here.
   ------------------------------------------------------------------- */
.dropdown {
    position: relative;
}

/*
 * A <summary> is a list item by default and paints a disclosure triangle.
 * The button display already suppresses it in most engines; the marker
 * rules cover the rest.
 */
.dropdown__toggle {
    cursor: pointer;
    list-style: none;
}

.dropdown__toggle::-webkit-details-marker {
    display: none;
}

.dropdown__toggle::marker {
    content: "";
}

.dropdown__menu {
    position: absolute;
    top: calc(100% + var(--space-2));
    right: 0;
    z-index: 20;
    min-width: 15rem;
    padding: var(--space-2);
    background-color: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-menu);
}

.dropdown__label {
    padding: var(--space-2);
    color: var(--color-text-muted);
    font-size: var(--fs-caption);
}

.dropdown__item {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    width: 100%;
    padding: var(--space-2);
    border-radius: var(--radius-sm);
    color: var(--color-text);
    font-size: var(--fs-body-3);
    text-align: left;
}

.dropdown__item:hover {
    background-color: var(--color-surface-alt);
    color: var(--color-text-strong);
}

.dropdown__item--danger { color: var(--color-danger); }
.dropdown__item--danger:hover {
    background-color: var(--color-danger-bg);
    color: var(--color-danger);
}

.dropdown__divider {
    height: 1px;
    margin: var(--space-2) 0;
    background-color: var(--color-border);
}

/* -------------------------------------------------------------------
   Message list

   Each row is one anchor laid out on a small grid. On a phone the grid
   stacks — sender and time on the first line, subject on the second —
   so the row fits the screen instead of scrolling sideways. From the md
   breakpoint the same markup becomes a single scannable line.
   ------------------------------------------------------------------- */
.mail-list {
    font-size: var(--fs-body-3);
}

.mail-list li + li {
    border-top: 1px solid var(--color-border);
}

.mail-row {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    grid-template-areas:
        "avatar sender  date"
        "avatar subject subject";
    align-items: center;
    column-gap: var(--space-3);
    row-gap: 2px;
    padding: var(--space-3) var(--space-5);
    color: var(--color-text);
    transition: background-color var(--transition-fast);
}

.mail-row:hover {
    background-color: var(--color-surface-alt);
    color: var(--color-text);
}

/*
 * Unread mail. The IMAP \Seen flag is already fetched for every row, so the
 * distinction costs nothing extra to show. Marked with weight, a stronger
 * subject colour and a dot, rather than weight alone.
 */
.mail-row--unread .mail-row__sender,
.mail-row--unread .mail-row__subject {
    font-weight: var(--fw-semibold);
    color: var(--color-text-strong);
}

/*
 * The brand orange behind a white letter measures 2.73:1 — below the 4.5:1
 * the initial needs — so the darkened brand tone carries it instead (5.15:1).
 */
.mail-row--unread .mail-row__avatar {
    background-color: var(--color-brand-ink);
    color: var(--color-surface);
}

.mail-row--unread .mail-row__date::after {
    content: "";
    display: inline-block;
    width: 6px;
    height: 6px;
    margin-left: var(--space-2);
    border-radius: var(--radius-pill);
    background-color: var(--color-brand);
    vertical-align: middle;
}

.mail-row__avatar { grid-area: avatar; }

.mail-row__sender {
    grid-area: sender;
    font-weight: var(--fw-medium);
    color: var(--color-text-strong);
}

.mail-row__subject {
    grid-area: subject;
    color: var(--color-text-muted);
}

.mail-row__date {
    grid-area: date;
    color: var(--color-text-muted);
    font-size: var(--fs-caption);
    white-space: nowrap;
}

/* Both need an explicit minimum before they will shorten instead of overflow. */
.mail-row__sender,
.mail-row__subject {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

@media (min-width: 768px) {
    .mail-row {
        grid-template-columns: auto 14rem minmax(0, 1fr) auto;
        grid-template-areas: "avatar sender subject date";
        column-gap: var(--space-4);
    }

    .mail-row__subject {
        color: var(--color-text-strong);
    }
}

/* -------------------------------------------------------------------
   Message body
   ------------------------------------------------------------------- */
.message__meta {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-1) var(--space-4);
    color: var(--color-text-muted);
    font-size: var(--fs-caption);
}

.message__subject {
    margin-block: var(--space-3) var(--space-4);
    font-size: var(--fs-h5);
    line-height: var(--lh-snug);
    color: var(--color-text-strong);
}

/*
 * The frame keeps a light surface in either appearance. Mail HTML sets its own
 * colours assuming a white page; turning the background dark underneath it
 * would leave black text on black.
 */
.message__frame {
    display: block;
    width: 100%;
    background-color: #ffffff;
    /* Fallback only: JavaScript measures the rendered mail and grows the
       frame. Without it the message keeps this height and scrolls inside. */
    min-height: 18rem;
    border: 0;
    border-radius: var(--radius-md);
}

.message__text {
    margin: 0;
    font-family: var(--font-mono);
    font-size: var(--fs-caption);
    line-height: var(--lh-relaxed);
    white-space: pre-wrap;
    word-break: break-word;
}

/* -------------------------------------------------------------------
   Empty state
   ------------------------------------------------------------------- */
.empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-9) var(--space-5);
    text-align: center;
}

.empty__icon {
    color: var(--color-brand);
}

.empty__text {
    max-width: 26rem;
    color: var(--color-text-muted);
}

/* -------------------------------------------------------------------
   Feature list (landing)
   ------------------------------------------------------------------- */
.feature {
    display: flex;
    gap: var(--space-3);
}

.feature + .feature {
    margin-top: var(--space-4);
}

.feature__icon {
    color: var(--color-brand-ink);
}

.feature__title {
    font-size: var(--fs-h6);
    line-height: var(--lh-snug);
    font-weight: var(--fw-semibold);
    color: var(--color-text-strong);
}

.feature__text {
    margin-top: var(--space-1);
    color: var(--color-text-muted);
}

/* -------------------------------------------------------------------
   Prose — long-form content pages
   Measure is capped at ~68 characters, which is the readable range for
   body text; wider lines lose the reader between rows.
   ------------------------------------------------------------------- */
.prose {
    max-width: 42rem;
    font-size: var(--fs-body-2);
    line-height: var(--lh-loose);
}

.prose__title {
    font-size: var(--fs-h3);
    line-height: var(--lh-normal);
    color: var(--color-text-strong);
    margin-bottom: var(--space-5);
}

.prose__lead {
    font-size: var(--fs-body-1);
    line-height: var(--lh-loose);
    color: var(--color-text-strong);
}

.prose h2 {
    margin-top: var(--space-7);
    margin-bottom: var(--space-3);
    font-size: var(--fs-h6);
    color: var(--color-text-strong);
}

.prose p + p,
.prose ul + p,
.prose p + ul {
    margin-top: var(--space-4);
}

.prose ul {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    padding-left: var(--space-5);
    list-style: disc;
}

.prose li::marker {
    color: var(--color-brand);
}

.prose a {
    color: var(--color-brand-ink);
    text-decoration: underline;
    text-underline-offset: 2px;
}

.prose code {
    padding: 0.1em 0.35em;
    border-radius: var(--radius-sm);
    background-color: var(--color-surface-alt);
    font-size: 0.9em;
}

.prose__cta {
    margin-top: var(--space-5);
}

.prose__meta {
    margin-top: var(--space-7);
    padding-top: var(--space-4);
    border-top: 1px solid var(--color-border);
    color: var(--color-text-muted);
    font-size: var(--fs-caption);
}

/* -------------------------------------------------------------------
   Page illustrations
   Decorative artwork beside long-form content. The drawings are solid
   duotone shapes in a single colour, so the hue is set once, here, and
   every fill inside them follows it through currentColor.

   Brand orange: these sit alone in their column with nothing to be
   confused with, and the reduced-opacity layers of the duotone keep the
   mass off them, so the accent can be the real one rather than a grey
   stand-in. Nothing here carries meaning, so no contrast floor applies.
   ------------------------------------------------------------------- */
.art {
    display: block;
    width: 100%;
    max-width: 13rem;
    height: auto;
    color: var(--color-brand);
}


/* -------------------------------------------------------------------
   Pagination
   ------------------------------------------------------------------- */
.pagination {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    margin-top: var(--space-4);
}

.pagination__status {
    color: var(--color-text-muted);
    font-size: var(--fs-caption);
    text-align: center;
}

.is-disabled {
    opacity: 0.45;
    pointer-events: none;
}

/* -------------------------------------------------------------------
   Attachments
   ------------------------------------------------------------------- */
.attachments {
    margin-top: var(--space-6);
    padding-top: var(--space-5);
    border-top: 1px solid var(--color-border);
}

.attachments__title {
    font-size: var(--fs-h6);
    line-height: var(--lh-snug);
    color: var(--color-text-strong);
    margin-bottom: var(--space-3);
}

.attachments__list {
    display: grid;
    gap: var(--space-2);
}

@media (min-width: 768px) {
    .attachments__list {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

.attachment {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-3);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    color: var(--color-text);
    transition: background-color var(--transition-fast), border-color var(--transition-fast);
}

.attachment:hover {
    background-color: var(--color-surface-alt);
    border-color: var(--color-text-muted);
    color: var(--color-text-strong);
}

.attachment__type {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 2.75rem;
    height: 2.75rem;
    border-radius: var(--radius-sm);
    background-color: var(--color-brand-tint);
    color: var(--color-brand-ink);
    font-size: 11px;
    font-weight: var(--fw-semibold);
}

.attachment__body {
    display: grid;
    flex: 1 1 auto;
}

.attachment__name {
    font-size: var(--fs-body-3);
    color: var(--color-text-strong);
}

.attachment__meta {
    font-size: var(--fs-caption);
    color: var(--color-text-muted);
}

.attachment__icon {
    flex-shrink: 0;
    color: var(--color-text-muted);
}

/* -------------------------------------------------------------------
   Mail list toolbar
   The address chip and the in-mailbox search share one row; the search
   takes the space the chip leaves and drops to its own line when there
   is not enough of it.
   ------------------------------------------------------------------- */
.mail-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2);
}

.search--inline {
    flex: 1 1 14rem;
    min-width: 0;
    margin-left: auto;
    max-width: 22rem;
}

.input--sm {
    padding: 0.4rem 0.7rem;
    font-size: var(--fs-caption);
}

.search--inline .search__control .input {
    padding-left: 2.1rem;
}

.search--inline .search__icon {
    left: 0.6rem;
}

/* -------------------------------------------------------------------
   Message actions and confirmation notice
   ------------------------------------------------------------------- */
.message__actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
}

.notice {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-3) var(--space-4);
    border-radius: var(--radius-md);
    background-color: var(--color-brand-tint);
    color: var(--color-brand-ink);
    font-size: var(--fs-body-3);
}
