/* ==========================================================================
   Replim base layer
   --------------------------------------------------------------------------
   Reset, typography and the primitives that appear on more than one surface:
   buttons, tags, platform badges, fields, alerts, icons.

   Requires tokens.css. Nothing here may contain a colour literal; if a value
   is missing from the token layer, add it there rather than hard coding here.
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }

html {
    -webkit-text-size-adjust: 100%;
    scroll-behavior: smooth;
}

body {
    margin: 0;
    background: var(--canvas);
    color: var(--ink);
    font-family: var(--font-sans);
    font-size: 16px;
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    font-feature-settings: "cv05" 1, "ss03" 1;  /* Inter: single storey l, curved r */
    overflow-x: hidden;
}

h1, h2, h3, h4, h5, h6 {
    margin: 0;
    font-weight: 500;
    line-height: 1.15;
    letter-spacing: -0.015em;
}
h1, h2 { font-family: var(--font-display); }
h3, h4, h5, h6 { font-family: var(--font-sans); font-weight: 600; letter-spacing: -0.01em; }

p { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }
a { color: inherit; text-decoration: none; }
img, svg, video { max-width: 100%; }
img, video { display: block; height: auto; }
button { font: inherit; color: inherit; background: none; border: none; padding: 0; cursor: pointer; }
input, select, textarea { font: inherit; color: inherit; }
table { border-collapse: collapse; width: 100%; }
hr { border: 0; border-top: 1px solid var(--line); margin: var(--sp-6) 0; }

code, kbd, samp, pre { font-family: var(--font-mono); font-size: 0.9em; }

::selection { background: var(--accent-soft); color: var(--accent-text); }

/* Focus. One ring everywhere, always the accent, never removed. */
:focus { outline: none; }
:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
    border-radius: var(--r-xs);
}

/* Scrollbars follow the theme rather than staying stock white. */
* {
    scrollbar-width: thin;
    scrollbar-color: var(--line-strong) transparent;
}
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb {
    background: var(--line-strong);
    border: 3px solid transparent;
    background-clip: content-box;
    border-radius: var(--r-pill);
}
*::-webkit-scrollbar-thumb:hover { background: var(--ink-faint); background-clip: content-box; }

/* Motion is only ever used to explain a state change, so removing it costs
   no meaning. Everything settles into its final state. */
@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}

/* ==========================================================================
   UTILITIES
   ========================================================================== */

/* The HTML hidden attribute is display:none in the UA sheet. Any later
   display:flex / block on the same element wins, which is how the inbox
   showed "Drafted by Replim" over an empty reply box. The spec's own
   suggested rule restores the attribute. */
[hidden] { display: none !important; }

.u-vh {
    position: absolute !important;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%);
    white-space: nowrap; border: 0;
}

.skip-link {
    position: absolute; left: var(--sp-3); top: -60px; z-index: var(--z-overlay);
    background: var(--ink); color: var(--canvas);
    padding: var(--sp-3) var(--sp-4); border-radius: var(--r-sm); font-weight: 600;
    transition: top var(--t-ui) var(--ease);
}
.skip-link:focus { top: var(--sp-3); }

.icon { flex: 0 0 auto; vertical-align: -0.15em; }
.icon--brand { vertical-align: -0.2em; }

.eyebrow {
    font-size: var(--t-2xs);
    font-weight: 600;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--accent-text);
}

.muted { color: var(--ink-2); }
.faint { color: var(--ink-3); }

/* A link out to the author's own profile on the platform. The trailing glyph
   marks it as leaving the product, and every use pairs it with screen reader
   text saying the link opens in a new tab. */
.author-link { display: inline-flex; align-items: center; gap: 4px; color: inherit; }
.author-link:hover { color: var(--accent-text); text-decoration: underline; }
.author-link__out { opacity: 0.55; }

/* Numerals in tables, counts and metrics line up in columns. */
.tnum { font-variant-numeric: tabular-nums; }

/* ==========================================================================
   BUTTONS
   One set for the whole product. The app used to carry .btn--ember and the
   landing .btn--primary for the same thing.
   ========================================================================== */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--sp-2);
    padding: 10px 18px;
    min-height: 42px;
    border: 1px solid transparent;
    border-radius: var(--r-pill);
    font-size: var(--t-body);
    font-weight: 600;
    line-height: 1.2;
    text-align: center;
    white-space: nowrap;
    cursor: pointer;
    transition:
        background var(--t-hover) var(--ease),
        border-color var(--t-hover) var(--ease),
        color var(--t-hover) var(--ease),
        transform var(--t-hover) var(--ease);
}
.btn:disabled, .btn[aria-disabled="true"] { opacity: 0.55; cursor: not-allowed; }
.btn:not(:disabled):active { transform: translateY(1px); }

.btn--lg { padding: 14px 26px; min-height: 52px; font-size: 1rem; }
.btn--sm { padding: 7px 14px; min-height: 34px; font-size: var(--t-sm); }
.btn--block { width: 100%; }
.btn--square { padding: 0; width: 38px; min-height: 38px; border-radius: var(--r-sm); }

.btn--primary { background: var(--accent-fill); color: var(--on-accent); }
.btn--primary:not(:disabled):hover { background: var(--accent-fill-hover); }

.btn--secondary { background: var(--surface); border-color: var(--line); color: var(--ink); }
.btn--secondary:not(:disabled):hover { border-color: var(--ink-3); }

.btn--ghost { background: transparent; border-color: var(--line); color: var(--ink); }
.btn--ghost:not(:disabled):hover { border-color: var(--ink-3); background: var(--surface); }

.btn--quiet { background: transparent; color: var(--ink-2); }
.btn--quiet:not(:disabled):hover { color: var(--ink); background: var(--tint); }

.btn--danger { background: transparent; border-color: var(--line); color: var(--neg); }
.btn--danger:not(:disabled):hover { background: var(--neg-bg); border-color: var(--neg); }

/* On an inverted band the neutral buttons have to flip too. */
.on-invert .btn--secondary,
.on-invert .btn--ghost { background: transparent; border-color: var(--invert-line); color: var(--invert-ink); }
.on-invert .btn--secondary:hover,
.on-invert .btn--ghost:hover { border-color: var(--invert-ink); }
.on-invert .btn--quiet { color: var(--invert-ink-2); }
.on-invert .btn--quiet:hover { color: var(--invert-ink); background: transparent; }

/* Inline loading state for submit buttons. */
.btn .spinner {
    display: none;
    width: 15px; height: 15px;
    border-radius: 50%;
    border: 2px solid currentColor;
    border-top-color: transparent;
    opacity: 0.9;
    animation: spin 0.7s linear infinite;
}
.btn.is-loading .spinner { display: inline-block; }
.btn.is-loading { pointer-events: none; }
@keyframes spin { to { transform: rotate(360deg); } }

/* ==========================================================================
   TAGS AND BADGES
   Sentiment and intent are always a label plus a colour, never colour alone.
   ========================================================================== */

.tag {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: var(--t-2xs);
    font-weight: 600;
    line-height: 1.4;
    padding: 3px 9px;
    border-radius: var(--r-pill);
    border: 1px solid transparent;
    white-space: nowrap;
}
.tag--positive,
.tag--done { background: var(--pos-bg); color: var(--pos); border-color: color-mix(in srgb, var(--pos) 22%, transparent); }
.tag--negative { background: var(--neg-bg); color: var(--neg); border-color: color-mix(in srgb, var(--neg) 22%, transparent); }
.tag--warn,
.tag--attention { background: var(--warn-bg); color: var(--warn); border-color: color-mix(in srgb, var(--warn) 22%, transparent); }
.tag--accent,
.tag--buying { background: var(--accent-soft); color: var(--accent-text); border-color: var(--accent-soft-line); }
.tag--neutral,
.tag--question,
.tag--repeat,
.tag--low { background: var(--tint); color: var(--ink-2); border-color: var(--line); }

.tag__dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex: 0 0 auto; }

/* Platform badge. Was .pbadge on the landing and .platform-badge in the app. */
.pbadge {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: var(--t-2xs);
    font-weight: 600;
    line-height: 1.4;
    padding: 3px 9px;
    border-radius: var(--r-pill);
    white-space: nowrap;
}
.pbadge--instagram { background: var(--tint-instagram); color: var(--ink-instagram); }
.pbadge--facebook  { background: var(--tint-facebook);  color: var(--ink-facebook); }
.pbadge--linkedin  { background: var(--tint-linkedin);  color: var(--ink-linkedin); }
.pbadge--youtube   { background: var(--tint-youtube);   color: var(--ink-youtube); }

/* Filter chip. Used by the inbox filters and by the landing demos, so it lives
   here rather than being defined twice with slightly different padding. */
.chip {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 6px 13px;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--r-pill);
    font-size: var(--t-sm); font-weight: 500;
    color: var(--ink-2);
    white-space: nowrap;
    transition: background var(--t-hover) var(--ease),
                border-color var(--t-hover) var(--ease),
                color var(--t-hover) var(--ease);
}
.chip:hover { border-color: var(--ink-3); color: var(--ink); }
.chip.is-active { background: var(--ink); border-color: var(--ink); color: var(--canvas); font-weight: 600; }
.chip__count { font-size: var(--t-2xs); color: var(--ink-3); font-variant-numeric: tabular-nums; }
.chip.is-active .chip__count { color: var(--canvas); opacity: 0.7; }

/* Keyboard hint, used by the inbox shortcuts. */
kbd.key {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 20px; padding: 2px 6px;
    background: var(--tint); border: 1px solid var(--line);
    border-bottom-width: 2px;
    border-radius: var(--r-xs);
    font-family: var(--font-sans); font-size: var(--t-2xs); font-weight: 600;
    color: var(--ink-2);
}

/* ==========================================================================
   AVATARS
   Initials on a warm tint. No generated gradients: the previous purple
   gradient avatars fought the accent on every screen they appeared.
   ========================================================================== */

.avatar {
    display: grid; place-items: center;
    width: 36px; height: 36px;
    flex: 0 0 auto;
    border-radius: 50%;
    background: var(--tint);
    border: 1px solid var(--line);
    color: var(--ink-2);
    font-size: var(--t-xs);
    font-weight: 600;
    letter-spacing: 0.02em;
    overflow: hidden;
}
.avatar--sm { width: 28px; height: 28px; font-size: var(--t-2xs); }
.avatar--lg { width: 44px; height: 44px; font-size: var(--t-sm); }
.avatar--square { border-radius: var(--r-sm); }
.avatar--accent { background: var(--accent-fill); border-color: transparent; color: var(--on-accent); }
.avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* ==========================================================================
   FIELDS
   Shared by auth, settings and the inbox composer.
   ========================================================================== */

.field { margin-bottom: var(--sp-4); }
.field:last-child { margin-bottom: 0; }

.field > label,
.field__label {
    display: block;
    font-size: var(--t-sm);
    font-weight: 600;
    margin-bottom: 6px;
    color: var(--ink);
}

.input,
.field input:not([type="checkbox"]):not([type="radio"]),
.field select,
.field textarea {
    width: 100%;
    padding: 10px 13px;
    background: var(--surface);
    border: 1px solid var(--line-strong);
    border-radius: var(--r-sm);
    font-size: var(--t-body);
    font-family: inherit;
    color: var(--ink);
    transition: border-color var(--t-hover) var(--ease), box-shadow var(--t-hover) var(--ease);
}
.field textarea { resize: vertical; min-height: 96px; line-height: 1.55; }

.input::placeholder,
.field input::placeholder,
.field textarea::placeholder { color: var(--ink-faint); }

.input:focus,
.field input:focus,
.field select:focus,
.field textarea:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-soft);
}
.field input.is-invalid,
.field textarea.is-invalid { border-color: var(--neg); }
.field input.is-invalid:focus { box-shadow: 0 0 0 3px var(--neg-bg); }

.field__hint { font-size: var(--t-xs); color: var(--ink-3); margin-top: 6px; }
.field__error {
    display: block; min-height: 16px; margin-top: 5px;
    font-size: var(--t-xs); color: var(--neg); font-weight: 500;
}
.field__row { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); }
.field__check { display: inline-flex; align-items: center; gap: var(--sp-2); font-size: var(--t-sm); color: var(--ink-2); }
.field__check input { width: auto; accent-color: var(--accent-fill); }

/* Toggle switch */
.switch {
    position: relative;
    width: 40px; height: 23px;
    flex: 0 0 auto;
    border-radius: var(--r-pill);
    background: var(--line-strong);
    transition: background var(--t-hover) var(--ease);
}
.switch__knob {
    position: absolute; top: 3px; left: 3px;
    width: 17px; height: 17px;
    border-radius: 50%;
    background: var(--w-0);
    box-shadow: var(--shadow-sm);
    transition: transform var(--t-hover) var(--ease);
}
.switch.is-on { background: var(--accent-fill); }
.switch.is-on .switch__knob { transform: translateX(17px); }

/* ==========================================================================
   ALERTS
   ========================================================================== */

.alert {
    display: none;
    align-items: flex-start;
    gap: var(--sp-2);
    padding: 11px 14px;
    margin-bottom: var(--sp-4);
    border: 1px solid transparent;
    border-radius: var(--r-sm);
    font-size: var(--t-sm);
    font-weight: 500;
    background: var(--neg-bg);
    color: var(--neg);
    border-color: color-mix(in srgb, var(--neg) 25%, transparent);
}
.alert.is-visible { display: flex; }
.alert--success { background: var(--pos-bg); color: var(--pos); border-color: color-mix(in srgb, var(--pos) 25%, transparent); }
.alert--notice { background: var(--warn-bg); color: var(--warn); border-color: color-mix(in srgb, var(--warn) 25%, transparent); }
.alert--static { display: flex; }

/* ==========================================================================
   BILLING CYCLE SWITCH
   Shared by pricing, signup and billing. Surfaces set layout (margin);
   the pill itself lives here so the three cannot drift.
   ========================================================================== */

.cycle { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.cycle__label {
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--ink-3);
    text-transform: uppercase;
    letter-spacing: 0.06em;
}
.cycle__switch {
    position: relative;
    display: inline-flex;
    gap: 4px;
    padding: 4px;
    background: var(--inset);
    border-radius: var(--r-pill);
}
.cycle__opt {
    display: inline-flex;
    align-items: center;
    position: relative;
    z-index: 1;
    border-radius: var(--r-pill);
    padding: var(--sp-2) var(--sp-4);
    min-height: 40px;
    font-size: 0.83rem;
    font-weight: 600;
    color: var(--ink-2);
    transition: background var(--t-hover) var(--ease), color var(--t-hover) var(--ease);
}
.cycle__opt.is-active,
.cycle__opt:has(:checked) {
    background: var(--surface);
    color: var(--ink);
    box-shadow: var(--shadow-sm);
}
.cycle__opt input[type="radio"] {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    margin: 0;
    opacity: 0;
    cursor: pointer;
}

/* ==========================================================================
   EMPTY STATES
   ========================================================================== */

.empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    padding: var(--sp-16) var(--sp-5);
    color: var(--ink-2);
}
.empty__mark {
    display: grid; place-items: center;
    width: 52px; height: 52px;
    margin-bottom: var(--sp-4);
    border-radius: var(--r-md);
    background: var(--tint);
    border: 1px solid var(--line);
    color: var(--ink-3);
}
.empty h3 { font-size: var(--t-head); color: var(--ink); margin-bottom: 6px; }
.empty p { max-width: var(--measure-narrow); font-size: var(--t-sm); }
.empty .btn { margin-top: var(--sp-5); }

/* ==========================================================================
   WORDMARK
   Two files, one per theme. Both are in the markup so a toggle does not wait
   on a fetch. Visibility follows the same rule as the canvas: system
   preference, unless the user has forced a theme.
   ========================================================================== */

.brand-logo {
    display: block;
    height: 28px;
    width: auto;
}
.brand-logo--dark { display: none; }

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .brand-logo--light { display: none; }
    :root:not([data-theme="light"]) .brand-logo--dark { display: block; }
}

:root[data-theme="dark"] .brand-logo--light { display: none; }
:root[data-theme="dark"] .brand-logo--dark { display: block; }

/* ==========================================================================
   THEME TOGGLE
   Three states: follow the system, force light, force dark. A two state
   toggle cannot express "follow the system", which is the default and the
   one most people want.
   ========================================================================== */

.theme-toggle {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    padding: 2px;
    background: var(--tint);
    border: 1px solid var(--line);
    border-radius: var(--r-pill);
}
.theme-toggle__btn {
    display: grid; place-items: center;
    width: 28px; height: 26px;
    border-radius: var(--r-pill);
    color: var(--ink-3);
    transition: background var(--t-hover) var(--ease), color var(--t-hover) var(--ease);
}
.theme-toggle__btn:hover { color: var(--ink); }
.theme-toggle__btn[aria-pressed="true"] {
    background: var(--surface);
    color: var(--ink);
    box-shadow: var(--shadow-sm);
}
