/* ==========================================================================
   Todos — styles

   A light grey desk with white cards on it. The header, the composer, the
   tabs and every task sit on white; each status carries its own colour:
   grey for Draft, amber for In progress, green for Done. Indigo is kept for
   the main actions. Tailwind utilities do the layout, this file holds the
   pieces that repeat.

   1. Base
   2. Status colours
   3. Labels
   4. Buttons
   5. Fields
   6. Composer
   7. Tabs
   8. Groups
   9. Tasks
   10. Status menu
   11. Attachments
   12. Trash
   13. Empty states
   14. App tabs
   15. Notifications
   16. Dialogs
   17. Image viewer
   18. Motion
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Base
   -------------------------------------------------------------------------- */

/* A clear ring on whatever has the keyboard focus. */
:where(a, button, input, textarea, select, [tabindex]):focus-visible {
    outline: 3px solid hsl(var(--primary));
    outline-offset: 2px;
    border-radius: 6px;
}

/* Titles that only take the focus so they are read aloud. */
:where(h1, h2)[tabindex='-1']:focus {
    outline: none;
}

/* On the dark photo viewer the ring turns white. */
.viewer :focus-visible {
    outline-color: hsl(var(--viewer-foreground));
}

::selection {
    background: hsl(var(--primary) / 0.16);
    color: hsl(var(--foreground));
}

html.is-locked,
html.is-locked body {
    overflow: hidden;
}

/* --------------------------------------------------------------------------
   2. Status colours
   --st is the colour of the status, --st-ink a darker shade for text on a
   light tint, so every label keeps a readable contrast.
   -------------------------------------------------------------------------- */

.st-draft {
    --st: var(--draft);
    --st-ink: 222 16% 34%;
}

.st-in_progress {
    --st: var(--progress);
    --st-ink: 26 90% 30%;
}

.st-completed {
    --st: var(--done);
    --st-ink: 152 62% 24%;
}

.st-trash {
    --st: var(--muted-foreground);
    --st-ink: 222 12% 34%;
}

/* --------------------------------------------------------------------------
   3. Labels
   -------------------------------------------------------------------------- */

.label {
    font-family: 'DM Mono', ui-monospace, SFMono-Regular, monospace;
    font-size: 0.6875rem;
    letter-spacing: 0.04em;
    color: hsl(var(--muted-foreground));
}

.label.is-full {
    color: hsl(var(--danger));
}

/* --------------------------------------------------------------------------
   4. Buttons
   -------------------------------------------------------------------------- */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.45rem;
    height: 2.5rem;
    padding: 0 1rem;
    border: 1px solid transparent;
    border-radius: 0.625rem;
    font-size: 0.875rem;
    font-weight: 600;
    line-height: 1;
    white-space: nowrap;
    cursor: pointer;
    transition:
        background-color 0.14s ease,
        border-color 0.14s ease,
        color 0.14s ease,
        box-shadow 0.14s ease,
        transform 0.14s ease;
}

.btn:active:not(:disabled) {
    transform: translateY(1px);
}

.btn-sm {
    height: 2.125rem;
    padding: 0 0.75rem;
    font-size: 0.8125rem;
}

.btn-primary {
    background: hsl(var(--primary));
    color: hsl(var(--primary-foreground));
    box-shadow: 0 1px 2px hsl(var(--primary) / 0.3),
        inset 0 1px 0 hsl(0 0% 100% / 0.14);
}

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

.btn-ghost {
    background: hsl(var(--card));
    border-color: hsl(var(--border));
    color: hsl(var(--foreground));
}

.btn-ghost:hover:not(:disabled) {
    background: hsl(var(--muted));
}

.btn-danger {
    background: hsl(var(--danger));
    color: hsl(var(--primary-foreground));
}

.btn-danger:hover:not(:disabled) {
    background: hsl(var(--danger) / 0.88);
}

.btn-soft-danger {
    background: hsl(var(--card));
    border-color: hsl(var(--border));
    color: hsl(var(--danger));
}

.btn-soft-danger:hover:not(:disabled) {
    background: hsl(var(--danger) / 0.07);
    border-color: hsl(var(--danger) / 0.35);
}

.btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* The quiet button inside the composer and the cards. */
.btn-subtle {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    height: 2.25rem;
    padding: 0 0.7rem;
    border-radius: 0.55rem;
    font-size: 0.8125rem;
    font-weight: 500;
    color: hsl(var(--muted-foreground));
    cursor: pointer;
    transition:
        background-color 0.14s ease,
        color 0.14s ease;
}

.btn-subtle:hover {
    background: hsl(var(--muted));
    color: hsl(var(--foreground));
}

.icon-btn {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    height: 2.125rem;
    width: 2.125rem;
    border-radius: 0.55rem;
    color: hsl(var(--muted-foreground));
    cursor: pointer;
    transition:
        background-color 0.14s ease,
        color 0.14s ease;
}

.icon-btn:hover {
    background: hsl(var(--muted));
    color: hsl(var(--foreground));
}

.icon-danger:hover {
    background: hsl(var(--danger) / 0.1);
    color: hsl(var(--danger));
}

/* --------------------------------------------------------------------------
   5. Fields
   -------------------------------------------------------------------------- */

.field {
    width: 100%;
    min-width: 0;
    height: 2.5rem;
    padding: 0 0.75rem;
    border: 1px solid hsl(var(--border));
    border-radius: 0.625rem;
    background: hsl(var(--card));
    font-size: 0.9375rem;
    color: hsl(var(--foreground));
    transition:
        border-color 0.14s ease,
        box-shadow 0.14s ease;
}

.field::placeholder {
    color: hsl(var(--muted-foreground));
}

.field:focus {
    outline: none;
    border-color: hsl(var(--primary));
    box-shadow: 0 0 0 3px hsl(var(--primary) / 0.35);
}

.field-area {
    display: block;
    height: auto;
    min-height: 2.5rem;
    padding: 0.5rem 0.75rem;
    line-height: 1.45rem;
    resize: none;
    overflow-y: hidden;
}

/* --------------------------------------------------------------------------
   6. Composer
   -------------------------------------------------------------------------- */

.composer {
    position: relative;
    border: 1px solid hsl(var(--border));
    border-radius: calc(var(--radius) + 0.125rem);
    background: hsl(var(--card));
    box-shadow: var(--shadow);
    transition:
        border-color 0.14s ease,
        box-shadow 0.14s ease;
}

.composer:focus-within {
    border-color: hsl(var(--primary));
    box-shadow:
        0 0 0 3px hsl(var(--primary) / 0.3),
        var(--shadow);
}

.composer-input {
    display: block;
    width: 100%;
    min-height: 3.25rem;
    padding: 0.95rem 1rem 0.35rem;
    border: 0;
    background: transparent;
    font-size: 1rem;
    line-height: 1.5rem;
    color: hsl(var(--foreground));
    resize: none;
    overflow-y: hidden;
}

.composer-input::placeholder {
    color: hsl(var(--muted-foreground));
}

.composer-input:focus,
.composer-input:focus-visible {
    outline: none;
}

.composer-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.25rem 0.5rem;
    padding: 0.4rem 0.55rem 0.55rem;
}

.add-status {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.75rem;
    color: hsl(var(--muted-foreground));
}

.add-status .dot {
    height: 0.5rem;
    width: 0.5rem;
    border-radius: 999px;
    background: hsl(var(--st));
}

.add-status b {
    font-weight: 600;
    color: hsl(var(--st-ink));
}

.attach-row {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    padding: 0.35rem 1rem 0.25rem;
}

.drop-hint {
    position: absolute;
    inset: 0;
    z-index: 5;
    display: none;
    align-items: center;
    justify-content: center;
    gap: 0.6rem;
    border: 2px dashed hsl(var(--primary));
    border-radius: inherit;
    background: hsl(var(--card) / 0.94);
    color: hsl(var(--primary));
    font-size: 0.9375rem;
    font-weight: 600;
    pointer-events: none;
}

.composer.is-dragging .drop-hint {
    display: flex;
}

/* --------------------------------------------------------------------------
   7. Tabs
   -------------------------------------------------------------------------- */

.tabs {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0.3rem;
    border: 1px solid hsl(var(--border));
    border-radius: calc(var(--radius) + 0.125rem);
    background: hsl(var(--card));
    box-shadow: var(--shadow);
    overflow-x: auto;
    scrollbar-width: none;
}

.tabs::-webkit-scrollbar {
    display: none;
}

.tab {
    --st: var(--primary);
    display: inline-flex;
    flex: none;
    align-items: center;
    gap: 0.45rem;
    height: 2.25rem;
    padding: 0 0.7rem;
    border-radius: 0.55rem;
    font-size: 0.875rem;
    font-weight: 500;
    white-space: nowrap;
    color: hsl(var(--muted-foreground));
    cursor: pointer;
    transition:
        background-color 0.14s ease,
        color 0.14s ease;
}

.tab:hover {
    background: hsl(var(--muted));
    color: hsl(var(--foreground));
}

.tab-icon {
    height: 1rem;
    width: 1rem;
    flex: none;
    color: hsl(var(--st));
}

.tab[data-view='all'] .tab-icon,
.tab-trash .tab-icon {
    color: currentColor;
}

.tab-count {
    display: inline-grid;
    place-items: center;
    min-width: 1.375rem;
    height: 1.25rem;
    padding: 0 0.35rem;
    border-radius: 999px;
    background: hsl(var(--muted));
    font-family: 'DM Mono', ui-monospace, SFMono-Regular, monospace;
    font-size: 0.6875rem;
    font-weight: 500;
    color: hsl(var(--muted-foreground));
}

.tab-count:empty {
    display: none;
}

.tab[aria-pressed='true'] {
    background: hsl(var(--foreground));
    color: hsl(var(--card));
}

.tab[aria-pressed='true'] .tab-count {
    background: hsl(var(--card) / 0.16);
    color: hsl(var(--card));
}

.tabs-sep {
    flex: none;
    width: 1px;
    height: 1.25rem;
    margin: 0 0.2rem 0 auto;
    background: hsl(var(--border));
}

.trash-note {
    display: flex;
    align-items: flex-start;
    gap: 0.55rem;
    margin-top: 0.875rem;
    padding: 0.7rem 0.85rem;
    border-radius: 0.625rem;
    background: hsl(var(--primary) / 0.06);
    font-size: 0.8125rem;
    line-height: 1.45;
    color: hsl(var(--foreground) / 0.8);
}

.trash-note svg {
    margin-top: 0.1rem;
    color: hsl(var(--primary));
}

/* --------------------------------------------------------------------------
   7b. Apps
   Every app carries its own colour, set as --app. --app-ink is a darker
   shade so its name stays readable on the light tint.
   -------------------------------------------------------------------------- */

.app-indigo { --app: 243 75% 59%; --app-ink: 243 60% 40%; }
.app-blue { --app: 212 85% 50%; --app-ink: 212 80% 32%; }
.app-teal { --app: 178 70% 36%; --app-ink: 178 80% 22%; }
.app-green { --app: 142 60% 38%; --app-ink: 142 65% 23%; }
.app-yellow { --app: 45 95% 45%; --app-ink: 35 90% 26%; }
.app-orange { --app: 24 92% 50%; --app-ink: 20 85% 32%; }
.app-red { --app: 0 72% 52%; --app-ink: 0 70% 36%; }
.app-pink { --app: 330 75% 55%; --app-ink: 330 70% 34%; }
.app-violet { --app: 270 65% 58%; --app-ink: 270 55% 38%; }
.app-gray { --app: 222 10% 50%; --app-ink: 222 14% 30%; }
.app-sky { --app: 199 89% 46%; --app-ink: 201 90% 28%; }
.app-lime { --app: 84 72% 40%; --app-ink: 86 78% 22%; }
.app-fuchsia { --app: 292 70% 52%; --app-ink: 292 68% 33%; }
.app-brown { --app: 25 46% 40%; --app-ink: 24 52% 25%; }
.app-black { --app: 222 24% 14%; --app-ink: 222 24% 14%; }

/* The top bar: logo, apps and buttons in one line on a computer. On a
   phone the apps get their own row under the logo. */
.site-bar {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    grid-template-areas:
        'brand . tools'
        'apps apps apps';
    align-items: center;
    column-gap: 0.75rem;
    width: 100%;
    max-width: 84rem;
    margin: 0 auto;
    padding: 0.625rem 1rem 0.5rem;
}

.site-brand {
    grid-area: brand;
    min-width: 0;
}

.site-tools {
    grid-area: tools;
}

/* The apps sit in the top bar, in one row that scrolls sideways when there
   are more than fit. The edges fade so it is clear there is more. */
.header-apps {
    grid-area: apps;
    position: relative;
    min-width: 0;
    margin: 0.4rem -0.15rem 0;
}

@media (min-width: 640px) {
    .site-bar {
        grid-template-areas: 'brand apps tools';
        height: 4rem;
        padding: 0 1rem;
    }

    .header-apps {
        margin: 0 0 0 0.5rem;
    }
}

.apps {
    display: flex;
    flex-wrap: nowrap;
    align-items: center;
    gap: 0.35rem;
    padding: 0.2rem 0.15rem;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-behavior: smooth;
    scrollbar-width: none;
    -webkit-mask-image: linear-gradient(to right, transparent 0, #000 0.6rem, #000 calc(100% - 1.25rem), transparent 100%);
    mask-image: linear-gradient(to right, transparent 0, #000 0.6rem, #000 calc(100% - 1.25rem), transparent 100%);
}

.apps::-webkit-scrollbar {
    display: none;
}

.apps .app-chip {
    flex: none;
    min-height: 2rem;
    padding: 0 0.7rem;
}

#apps-manage[aria-expanded='true'] {
    background: hsl(var(--muted));
    color: hsl(var(--foreground));
}

@media (prefers-reduced-motion: reduce) {
    .apps {
        scroll-behavior: auto;
    }
}

.app-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    min-height: 2.25rem;
    padding: 0 0.8rem;
    border: 1px solid hsl(var(--border));
    border-radius: 999px;
    background: hsl(var(--card));
    font-size: 0.8125rem;
    font-weight: 500;
    color: hsl(var(--foreground));
    cursor: pointer;
    transition:
        background-color 0.14s ease,
        border-color 0.14s ease;
}

.app-chip:hover {
    border-color: hsl(var(--app) / 0.6);
    background: hsl(var(--app) / 0.06);
}

.app-dot {
    height: 0.6rem;
    width: 0.6rem;
    flex: none;
    border-radius: 999px;
    background: hsl(var(--app));
}

.app-chip[aria-pressed='true'] {
    border-color: hsl(var(--app-ink));
    background: hsl(var(--app) / 0.14);
    color: hsl(var(--app-ink));
    font-weight: 600;
    box-shadow: inset 0 0 0 1px hsl(var(--app-ink));
}

/* The selected chip also shows a tick, so the choice never relies on
   colour alone. */
.app-chip .app-tick {
    display: none;
    height: 0.9rem;
    width: 0.9rem;
}

.app-chip[aria-pressed='true'] .app-tick {
    display: block;
}

.app-chip[aria-pressed='true'] .app-dot {
    display: none;
}

.app-count {
    font-family: 'DM Mono', ui-monospace, SFMono-Regular, monospace;
    font-size: 0.6875rem;
    opacity: 0.8;
}

/* The app tag on a task. */
.app-tag {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    height: 1.625rem;
    padding: 0 0.55rem;
    border-radius: 999px;
    background: hsl(var(--app) / 0.12);
    font-size: 0.75rem;
    font-weight: 600;
    color: hsl(var(--app-ink));
    cursor: pointer;
}

.app-tag:hover {
    background: hsl(var(--app) / 0.2);
}

.app-tag-none {
    --app: var(--muted-foreground);
    --app-ink: var(--muted-foreground);
    background: transparent;
    border: 1px dashed hsl(var(--border));
    font-weight: 500;
}

/* Rows in the "Menaxho aplikacionet" window. */
.app-rows {
    display: grid;
    gap: 0.5rem;
}

.app-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.field-label {
    display: block;
    margin-bottom: 0.35rem;
    font-size: 0.8125rem;
    font-weight: 600;
    color: hsl(var(--foreground));
}

/* The colours sit in two full rows of eight, the last one a colour of
   one's own. Each round swatch grows with the window up to --swatch. */
.color-pick {
    --swatch: 2.25rem;
    display: grid;
    grid-template-columns: repeat(8, minmax(0, 1fr));
    justify-items: center;
    gap: 0.55rem 0.4rem;
    margin-top: 0.5rem;
    border: 0;
    padding: 0;
}

.color-pick label {
    position: relative;
    display: grid;
    place-items: center;
    width: 100%;
    max-width: var(--swatch);
    aspect-ratio: 1;
    border-radius: 999px;
    background: hsl(var(--app));
    cursor: pointer;
    transition: transform 0.14s ease;
}

.color-pick label:hover {
    transform: scale(1.08);
}

/* On the light colours the tick turns dark, so it stays easy to see. */
.color-pick .app-yellow svg,
.color-pick .app-lime svg {
    color: hsl(var(--foreground));
}

.color-pick input {
    position: absolute;
    opacity: 0;
    inset: 0;
    cursor: pointer;
}

.color-pick svg {
    display: none;
    height: 1rem;
    width: 1rem;
    color: hsl(0 0% 100%);
}

.color-pick input:checked + svg {
    display: block;
}

.color-pick label:focus-within {
    outline: 2px solid hsl(var(--foreground));
    outline-offset: 2px;
}

/* --------------------------------------------------------------------------
   8. Groups
   In "Të gjitha" the tasks are split by status, each with its colour.
   -------------------------------------------------------------------------- */

.group + .group {
    margin-top: 1.75rem;
}

.group-head {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin: 0 0 0.625rem;
    padding: 0 0.25rem;
    font-size: 0.8125rem;
    font-weight: 600;
    letter-spacing: 0;
    color: hsl(var(--st-ink));
}

.group-head svg {
    height: 1rem;
    width: 1rem;
    color: hsl(var(--st));
}

.group-count {
    padding: 0.1rem 0.45rem;
    border-radius: 999px;
    background: hsl(var(--st) / 0.13);
    font-family: 'DM Mono', ui-monospace, SFMono-Regular, monospace;
    font-size: 0.6875rem;
    font-weight: 500;
    color: hsl(var(--st-ink));
}

.group-line {
    flex: 1;
    height: 1px;
    background: linear-gradient(to right, hsl(var(--st) / 0.35), transparent);
}

.task-list {
    display: grid;
    gap: 0.5rem;
}

/* --------------------------------------------------------------------------
   9. Tasks
   -------------------------------------------------------------------------- */

.task {
    position: relative;
    display: flex;
    align-items: flex-start;
    gap: 0.7rem;
    padding: 0.75rem 0.6rem 0.7rem 0.85rem;
    border: 1px solid hsl(var(--border));
    border-radius: var(--radius);
    background: hsl(var(--card));
    box-shadow: var(--shadow);
    transition:
        border-color 0.14s ease,
        box-shadow 0.14s ease;
}

/* The thin colour edge that tells the status at a glance. */
.task::before {
    content: '';
    position: absolute;
    left: -1px;
    top: 0.85rem;
    bottom: 0.85rem;
    width: 3px;
    border-radius: 0 3px 3px 0;
    background: hsl(var(--st));
}

.task:hover {
    border-color: hsl(var(--muted-foreground) / 0.35);
}

.task:focus-within {
    border-color: hsl(var(--primary) / 0.4);
}

.task.is-editing {
    border-color: hsl(var(--primary) / 0.55);
    box-shadow:
        0 0 0 4px hsl(var(--primary) / 0.08),
        var(--shadow);
}

.status-btn {
    position: relative;
    display: inline-flex;
    flex: none;
    align-items: center;
    justify-content: center;
    height: 1.625rem;
    width: 1.625rem;
    margin-top: 0.05rem;
    border-radius: 999px;
    color: hsl(var(--st));
    cursor: pointer;
    transition:
        background-color 0.14s ease,
        transform 0.14s ease;
}

.status-btn::after {
    content: '';
    position: absolute;
    inset: -0.45rem;
}

.status-btn:hover {
    background: hsl(var(--st) / 0.12);
}

.status-btn:active {
    transform: scale(0.9);
}

.status-btn svg {
    height: 1.25rem;
    width: 1.25rem;
}

.ic-knock {
    stroke: hsl(var(--card));
}

.task-main {
    flex: 1;
    min-width: 0;
}

.task-text {
    display: block;
    width: 100%;
    padding: 0.125rem 0;
    text-align: left;
    font-size: 0.9375rem;
    line-height: 1.45rem;
    color: hsl(var(--foreground));
    cursor: text;
}

.task-body {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 6;
    line-clamp: 6;
    overflow: hidden;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

.task-text:hover .task-body {
    color: hsl(var(--primary));
}

.st-completed .task-body {
    color: hsl(var(--muted-foreground));
    text-decoration: line-through;
    text-decoration-color: hsl(var(--muted-foreground) / 0.55);
}

.task-foot {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem 0.6rem;
    margin-top: 0.55rem;
}

.task-actions {
    display: flex;
    flex: none;
    align-items: center;
    gap: 0.05rem;
    margin-top: -0.15rem;
}

.editor-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    margin-top: 0.5rem;
}

.editor-hint {
    margin-right: auto;
}

@media (hover: none) {
    .editor-hint {
        display: none;
    }
}

/* News about a task that arrives while its editor is open. */
.editor-note {
    margin-top: 0.75rem;
    padding: 0.55rem 0.75rem;
    border-left: 3px solid hsl(var(--warning));
    border-radius: 0.5rem;
    background: hsl(var(--warning) / 0.08);
    font-size: 0.8125rem;
    line-height: 1.45;
    color: hsl(var(--foreground) / 0.85);
}

/* --------------------------------------------------------------------------
   10. Status menu
   -------------------------------------------------------------------------- */

.status-wrap {
    position: relative;
}

.status-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    height: 1.625rem;
    padding: 0 0.45rem 0 0.55rem;
    border-radius: 999px;
    background: hsl(var(--st) / 0.12);
    font-size: 0.75rem;
    font-weight: 600;
    color: hsl(var(--st-ink));
    cursor: pointer;
    transition: background-color 0.14s ease;
}

.status-pill:hover,
.status-pill[aria-expanded='true'] {
    background: hsl(var(--st) / 0.2);
}

.status-pill .dot {
    height: 0.45rem;
    width: 0.45rem;
    border-radius: 999px;
    background: hsl(var(--st));
}

/* Menus float above everything and are placed next to their button by the
   script, opening upwards when there is no room below. */
.menu {
    position: fixed;
    top: 0;
    left: 0;
    z-index: 88;
    min-width: 12.5rem;
    max-width: calc(100vw - 1rem);
    max-height: calc(100dvh - 1rem);
    overflow-y: auto;
    padding: 0.3rem;
    border: 1px solid hsl(var(--border));
    border-radius: 0.75rem;
    background: hsl(var(--card));
    box-shadow: 0 16px 40px -12px hsl(var(--foreground) / 0.28);
    animation: pop-in 0.12s ease-out;
}

.menu-item {
    display: flex;
    width: 100%;
    align-items: center;
    gap: 0.6rem;
    height: 2.375rem;
    padding: 0 0.6rem;
    border-radius: 0.5rem;
    font-size: 0.875rem;
    font-weight: 500;
    text-align: left;
    color: hsl(var(--foreground));
    cursor: pointer;
}

.menu-item:hover,
.menu-item:focus-visible {
    background: hsl(var(--muted));
}

.menu-item:focus-visible {
    outline: 2px solid hsl(var(--primary));
    outline-offset: -2px;
}

.menu-item > svg:first-child {
    height: 1.05rem;
    width: 1.05rem;
    color: hsl(var(--st));
}

.menu-check {
    margin-left: auto;
    color: hsl(var(--primary));
    opacity: 0;
}

.menu-item[aria-checked='true'] .menu-check {
    opacity: 1;
}

/* --------------------------------------------------------------------------
   11. Attachments
   -------------------------------------------------------------------------- */

.thumbs {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-top: 0.6rem;
}

.thumb {
    position: relative;
    height: 4.75rem;
    width: 4.75rem;
    overflow: hidden;
    border: 1px solid hsl(var(--border));
    border-radius: 0.625rem;
    background: hsl(var(--muted));
}

.thumb-lg {
    height: 10rem;
    width: min(100%, 15rem);
}

.thumb-open {
    display: grid;
    place-items: center;
    height: 100%;
    width: 100%;
    color: hsl(var(--muted-foreground));
    cursor: zoom-in;
}

.thumb-open:focus-visible {
    outline-offset: -2px;
}

.thumb-open img {
    height: 100%;
    width: 100%;
    object-fit: cover;
    transition: transform 0.25s ease;
}

.thumb-open:hover img {
    transform: scale(1.05);
}

.thumb-remove {
    position: absolute;
    top: 0.3rem;
    right: 0.3rem;
    display: grid;
    place-items: center;
    height: 1.625rem;
    width: 1.625rem;
    border-radius: 999px;
    background: hsl(var(--viewer) / 0.62);
    color: hsl(var(--viewer-foreground));
    opacity: 0;
    cursor: pointer;
    transition:
        opacity 0.14s ease,
        background-color 0.14s ease;
}

.thumb:hover .thumb-remove,
.thumb:focus-within .thumb-remove {
    opacity: 1;
}

.thumb-remove:hover {
    background: hsl(var(--danger));
}

@media (hover: none) {
    .thumb-remove {
        opacity: 1;
    }
}

.files {
    display: grid;
    gap: 0.375rem;
    margin-top: 0.6rem;
}

.file {
    display: flex;
    align-items: center;
    gap: 0.15rem;
    max-width: 26rem;
    padding: 0.2rem;
    border: 1px solid hsl(var(--border));
    border-radius: 0.625rem;
    background: hsl(var(--muted) / 0.55);
}

.file-open {
    display: flex;
    flex: 1;
    min-width: 0;
    align-items: center;
    gap: 0.6rem;
    padding: 0.2rem 0.35rem;
    border-radius: 0.45rem;
    text-align: left;
    cursor: pointer;
    transition: background-color 0.14s ease;
}

.file-open:hover {
    background: hsl(var(--card));
}

.file-ext {
    display: grid;
    flex: none;
    place-items: center;
    height: 2.125rem;
    width: 2.125rem;
    border: 1px solid hsl(var(--border));
    border-radius: 0.45rem;
    background: hsl(var(--card));
    font-family: 'DM Mono', ui-monospace, SFMono-Regular, monospace;
    font-size: 0.5625rem;
    font-weight: 500;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    color: hsl(var(--primary));
}

.file-info {
    display: flex;
    min-width: 0;
    flex-direction: column;
    line-height: 1.2;
}

.file-name {
    overflow: hidden;
    font-size: 0.8125rem;
    font-weight: 500;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: hsl(var(--foreground));
}

.file-size {
    margin-top: 0.1rem;
    font-size: 0.6875rem;
    color: hsl(var(--muted-foreground));
}

.file-open .file-go {
    margin-left: auto;
    flex: none;
    color: hsl(var(--muted-foreground));
}

/* A file on its way up, in the composer or in a card. */
.chip {
    position: relative;
    display: inline-flex;
    max-width: 100%;
    align-items: center;
    gap: 0.5rem;
    min-height: 2.875rem;
    padding: 0.3rem 0.2rem 0.3rem 0.3rem;
    border: 1px solid hsl(var(--border));
    border-radius: 0.625rem;
    background: hsl(var(--card));
}

.chip-media {
    position: relative;
    display: grid;
    flex: none;
    place-items: center;
    height: 2.25rem;
    width: 2.25rem;
    overflow: hidden;
    border-radius: 0.45rem;
    background: hsl(var(--muted));
    color: hsl(var(--muted-foreground));
}

.chip-media img {
    height: 100%;
    width: 100%;
    object-fit: cover;
}

.chip-media .chip-busy {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    background: hsl(var(--card) / 0.65);
    color: hsl(var(--primary));
}

.chip-text {
    display: flex;
    min-width: 0;
    flex-direction: column;
    line-height: 1.2;
}

.chip-name {
    max-width: 10.5rem;
    overflow: hidden;
    font-size: 0.8125rem;
    font-weight: 500;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.chip-meta {
    font-size: 0.6875rem;
    color: hsl(var(--muted-foreground));
}

.chip.is-error {
    border-color: hsl(var(--danger) / 0.45);
    background: hsl(var(--danger) / 0.04);
}

.chip.is-error .chip-meta {
    color: hsl(var(--danger));
}

.chip .icon-btn {
    height: 1.875rem;
    width: 1.875rem;
}

/* A thin bar that fills while a file is on its way up. */
.progress {
    position: relative;
    display: block;
    height: 0.3125rem;
    width: 100%;
    overflow: hidden;
    border-radius: 999px;
    background: hsl(var(--muted));
}

.progress-bar {
    display: block;
    height: 100%;
    width: 0;
    border-radius: inherit;
    background: hsl(var(--primary));
    transition: width 0.2s ease;
}

.chip-progress {
    margin-top: 0.3rem;
    min-width: 6.5rem;
}

/* --------------------------------------------------------------------------
   12. Trash
   -------------------------------------------------------------------------- */

.task-trash .task-body {
    color: hsl(var(--muted-foreground));
}

.trash-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.35rem 0.75rem;
    margin-top: 0.4rem;
    font-size: 0.75rem;
    color: hsl(var(--muted-foreground));
}

.trash-meta span {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
}

/* --------------------------------------------------------------------------
   13. Empty states
   -------------------------------------------------------------------------- */

.empty {
    --st: var(--primary);
    --st-ink: var(--primary);
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 3rem 1.5rem;
    border: 1.5px dashed hsl(var(--border));
    border-radius: var(--radius);
    background: hsl(var(--card) / 0.6);
    text-align: center;
}

.empty-icon {
    display: grid;
    place-items: center;
    height: 3.5rem;
    width: 3.5rem;
    margin-bottom: 1rem;
    border-radius: 1rem;
    background: hsl(var(--st) / 0.12);
    color: hsl(var(--st));
}

.empty-icon svg {
    height: 1.6rem;
    width: 1.6rem;
}

.empty-title {
    font-size: 1rem;
    font-weight: 600;
    color: hsl(var(--foreground));
}

.empty-text {
    max-width: 23rem;
    margin-top: 0.35rem;
    font-size: 0.875rem;
    line-height: 1.5;
    color: hsl(var(--muted-foreground));
}

/* --------------------------------------------------------------------------
   14. App tabs
   The apps sit as tabs in their own row under the top bar. The open app is
   underlined in its own colour, and each tab shows the icon of its website
   or a dot in its colour. The + and the settings sit at the end.
   -------------------------------------------------------------------------- */

/* Every chip starts in the ink colour; an app colour always wins over it. */
:where(.app-chip) {
    --app: var(--foreground);
    --app-ink: var(--foreground);
}

.site-bar {
    grid-template-areas: 'brand . tools';
    height: 3.5rem;
    padding: 0 1rem;
}

@media (min-width: 640px) {
    .site-bar {
        grid-template-areas: 'brand . tools';
        height: 3.75rem;
    }
}

.app-bar {
    border-top: 1px solid hsl(var(--border) / 0.7);
}

.app-bar-inner {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    width: 100%;
    max-width: 84rem;
    margin: 0 auto;
    padding: 0 0.5rem 0 1rem;
}

.app-tabs {
    display: flex;
    flex: 1;
    min-width: 0;
    align-items: stretch;
    gap: 0.125rem;
    margin-left: -0.6rem;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-behavior: smooth;
    scrollbar-width: none;
    -webkit-mask-image: linear-gradient(to right, transparent 0, #000 0.6rem, #000 calc(100% - 1.5rem), transparent 100%);
    mask-image: linear-gradient(to right, transparent 0, #000 0.6rem, #000 calc(100% - 1.5rem), transparent 100%);
}

.app-tabs::-webkit-scrollbar {
    display: none;
}

.app-tabs .app-chip {
    position: relative;
    flex: none;
    gap: 0.5rem;
    min-height: 2.875rem;
    padding: 0 0.7rem;
    border: 0;
    border-radius: 0;
    background: transparent;
    box-shadow: none;
    font-size: 0.8125rem;
    font-weight: 500;
    color: hsl(var(--muted-foreground));
}

/* The line under the open tab grows from its middle. */
.app-tabs .app-chip::after {
    content: '';
    position: absolute;
    left: 0.55rem;
    right: 0.55rem;
    bottom: 0;
    height: 2.5px;
    border-radius: 3px 3px 0 0;
    background: hsl(var(--app));
    opacity: 0;
    transform: scaleX(0.3);
    transition:
        transform 0.2s ease,
        opacity 0.2s ease;
}

.app-tabs .app-chip:hover {
    background: transparent;
    color: hsl(var(--foreground));
}

.app-tabs .app-chip:hover::after {
    opacity: 0.35;
}

.app-tabs .app-chip[aria-pressed='true'] {
    border: 0;
    background: transparent;
    box-shadow: none;
    color: hsl(var(--app-ink));
    font-weight: 600;
}

.app-tabs .app-chip[aria-pressed='true']::after {
    opacity: 1;
    transform: none;
}

.app-tabs .app-chip[aria-pressed='true'] .app-dot {
    display: block;
}

.app-tabs .app-chip:focus-visible {
    outline-offset: -3px;
}

.app-tabs .app-count {
    min-width: 1.25rem;
    padding: 0.1rem 0.35rem;
    border-radius: 999px;
    background: hsl(var(--muted));
    text-align: center;
    color: hsl(var(--muted-foreground));
    opacity: 1;
}

.app-tabs .app-chip[aria-pressed='true'] .app-count {
    background: hsl(var(--app) / 0.14);
    color: hsl(var(--app-ink));
}

.app-all {
    height: 0.95rem;
    width: 0.95rem;
}

/* The icon of a website, framed in the colour of its app. */
.app-fav {
    flex: none;
    height: 1rem;
    width: 1rem;
    border-radius: 0.3rem;
    background: hsl(var(--card));
    object-fit: contain;
    box-shadow:
        0 0 0 1.5px hsl(var(--card)),
        0 0 0 3px hsl(var(--app) / 0.55);
}

.app-tag .app-fav,
.panel-item .app-fav {
    height: 0.875rem;
    width: 0.875rem;
    box-shadow: none;
}

.app-bar-tools {
    display: flex;
    flex: none;
    align-items: center;
    gap: 0.125rem;
    padding-left: 0.375rem;
    border-left: 1px solid hsl(var(--border));
}

.app-bar-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.35rem;
    height: 2.125rem;
    min-width: 2.125rem;
    padding: 0 0.55rem;
    border-radius: 0.55rem;
    font-size: 0.8125rem;
    font-weight: 600;
    color: hsl(var(--muted-foreground));
    cursor: pointer;
    transition:
        background-color 0.14s ease,
        color 0.14s ease;
}

.app-bar-btn:hover {
    background: hsl(var(--muted));
    color: hsl(var(--foreground));
}

.app-bar-btn svg {
    flex: none;
    height: 1rem;
    width: 1rem;
}

/* A new app, as the last chip of a row. */
.app-chip-add {
    border-style: dashed;
    color: hsl(var(--muted-foreground));
}

/* A colour of one's own, after the ready ones. */
.color-own {
    position: relative;
    display: grid;
    place-items: center;
    width: 100%;
    max-width: var(--swatch, 2.25rem);
    aspect-ratio: 1;
    padding: 3px;
    border-radius: 999px;
    background: conic-gradient(from 90deg, #ef4444, #f59e0b, #22c55e, #06b6d4, #6366f1, #d946ef, #ef4444);
}

.color-own input {
    height: 100%;
    width: 100%;
    padding: 0;
    border: 2px solid hsl(var(--card));
    border-radius: 999px;
    background: hsl(var(--card));
    cursor: pointer;
    -webkit-appearance: none;
    appearance: none;
}

.color-own input::-webkit-color-swatch-wrapper {
    padding: 0;
}

.color-own input::-webkit-color-swatch {
    border: 0;
    border-radius: 999px;
}

.color-own input::-moz-color-swatch {
    border: 0;
    border-radius: 999px;
}

.color-own.is-on {
    outline: 2px solid hsl(var(--foreground));
    outline-offset: 2px;
}

.url-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.url-preview {
    display: grid;
    flex: none;
    place-items: center;
    height: 2.5rem;
    width: 2.5rem;
    border: 1px solid hsl(var(--border));
    border-radius: 0.625rem;
    background: hsl(var(--muted) / 0.6);
    color: hsl(var(--muted-foreground));
}

.url-preview .app-fav {
    height: 1.25rem;
    width: 1.25rem;
    box-shadow: none;
}

.link-danger {
    color: hsl(var(--danger));
}

@media (prefers-reduced-motion: reduce) {
    .app-tabs {
        scroll-behavior: auto;
    }

    .app-tabs .app-chip::after {
        transition: none;
    }
}

@media (pointer: coarse) {
    .app-tabs .app-chip {
        min-height: 3rem;
    }

    .app-bar-btn {
        height: 2.75rem;
        min-width: 2.75rem;
    }

    .color-pick {
        --swatch: 2.75rem;
    }
}

@media (forced-colors: active) {
    .app-tabs .app-chip[aria-pressed='true']::after {
        forced-color-adjust: none;
        background: Highlight;
    }
}

/* --------------------------------------------------------------------------
   15. Notifications
   -------------------------------------------------------------------------- */

.toast {
    pointer-events: auto;
    display: flex;
    align-items: center;
    gap: 0.7rem;
    padding: 0.65rem 0.75rem;
    border: 1px solid hsl(var(--border));
    border-left: 3px solid hsl(var(--muted-foreground));
    border-radius: 0.625rem;
    background: hsl(var(--card));
    font-size: 0.8125rem;
    color: hsl(var(--foreground));
    box-shadow: 0 12px 32px -12px hsl(var(--foreground) / 0.3);
    animation: toast-in 0.16s ease-out;
}

.toast.is-leaving {
    animation: toast-out 0.14s ease-in forwards;
}

.toast-ok {
    border-left-color: hsl(var(--success));
}

.toast-error {
    border-left-color: hsl(var(--danger));
}

.toast-info {
    border-left-color: hsl(var(--primary));
}

/* Each notice also carries an icon, so its kind never relies on colour. */
.toast-icon {
    display: grid;
    flex: none;
    place-items: center;
    color: hsl(var(--primary));
}

.toast-ok .toast-icon {
    color: hsl(var(--success));
}

.toast-error .toast-icon {
    color: hsl(var(--danger));
}

.toast-body {
    flex: 1;
    min-width: 0;
}

.toast-text {
    line-height: 1.35;
}

.toast-action {
    flex: none;
    font-size: 0.8125rem;
    font-weight: 600;
    color: hsl(var(--primary));
    cursor: pointer;
}

.toast-action:hover {
    text-decoration: underline;
    text-underline-offset: 3px;
}

/* --------------------------------------------------------------------------
   16. Dialogs
   -------------------------------------------------------------------------- */

.dialog-backdrop {
    position: fixed;
    inset: 0;
    z-index: 80;
    display: flex;
    align-items: flex-end;
    justify-content: center;
    background: hsl(var(--foreground) / 0.4);
    animation: fade-in 0.14s ease-out;
}

.dialog-panel {
    width: 100%;
    max-width: 27rem;
    max-height: 92dvh;
    overflow-y: auto;
    padding: 1.35rem;
    border: 1px solid hsl(var(--border));
    border-radius: 1rem 1rem 0 0;
    background: hsl(var(--card));
    box-shadow: 0 24px 60px -20px hsl(var(--foreground) / 0.45);
    animation: sheet-in 0.16s ease-out;
}

@media (min-width: 640px) {
    .dialog-backdrop {
        align-items: center;
        padding: 1rem;
    }

    .dialog-panel {
        border-radius: 1rem;
    }
}

/* --------------------------------------------------------------------------
   17. Image viewer
   -------------------------------------------------------------------------- */

.viewer {
    position: fixed;
    inset: 0;
    z-index: 90;
    display: flex;
    flex-direction: column;
    background: hsl(var(--viewer) / 0.96);
    color: hsl(var(--viewer-foreground));
    animation: fade-in 0.16s ease-out;
}

.viewer-top {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0.5rem 0.6rem;
    padding-top: max(0.5rem, env(safe-area-inset-top));
}

.viewer-info {
    flex: 1;
    min-width: 0;
    padding: 0 0.4rem;
}

.viewer-name {
    overflow: hidden;
    font-size: 0.875rem;
    font-weight: 500;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.viewer-count {
    font-family: 'DM Mono', ui-monospace, SFMono-Regular, monospace;
    font-size: 0.6875rem;
    opacity: 0.65;
}

.viewer-btn {
    display: inline-grid;
    flex: none;
    place-items: center;
    height: 2.5rem;
    width: 2.5rem;
    border-radius: 0.625rem;
    color: inherit;
    opacity: 0.85;
    cursor: pointer;
    transition:
        background-color 0.14s ease,
        opacity 0.14s ease;
}

.viewer-btn:hover:not(:disabled) {
    background: hsl(var(--viewer-foreground) / 0.12);
    opacity: 1;
}

.viewer-btn:disabled {
    opacity: 0.3;
    cursor: default;
}

.viewer-btn svg {
    height: 1.2rem;
    width: 1.2rem;
}

.viewer-zoom {
    min-width: 3.1rem;
    font-family: 'DM Mono', ui-monospace, SFMono-Regular, monospace;
    font-size: 0.6875rem;
    text-align: center;
    opacity: 0.75;
}

@media (max-width: 479px) {
    .viewer-zoom,
    .viewer-hide-sm {
        display: none;
    }
}

.viewer-stage {
    position: relative;
    display: flex;
    flex: 1;
    min-height: 0;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    padding: 0.5rem 0.75rem;
    touch-action: none;
    user-select: none;
    -webkit-user-select: none;
    cursor: grab;
}

.viewer-stage.is-zoomed {
    cursor: move;
}

@media (min-width: 640px) {
    .viewer-stage {
        padding: 0.75rem 4.75rem;
    }
}

.viewer-img {
    max-height: 100%;
    max-width: 100%;
    object-fit: contain;
    border-radius: 0.25rem;
    transform-origin: center center;
    will-change: transform;
    -webkit-user-drag: none;
    user-select: none;
    box-shadow: 0 24px 70px -24px hsl(var(--viewer) / 0.9);
}

.viewer-img.is-smooth {
    transition: transform 0.22s ease;
}

.viewer-img.is-placeholder {
    filter: blur(10px) saturate(1.1);
    opacity: 0.8;
}

.viewer-img[hidden] {
    display: none;
}

.viewer-nav {
    position: absolute;
    top: 50%;
    z-index: 2;
    display: none;
    place-items: center;
    height: 2.875rem;
    width: 2.875rem;
    margin-top: -1.4375rem;
    border-radius: 999px;
    background: hsl(var(--viewer-foreground) / 0.1);
    color: hsl(var(--viewer-foreground));
    cursor: pointer;
    transition: background-color 0.14s ease;
}

.viewer-nav:hover {
    background: hsl(var(--viewer-foreground) / 0.2);
}

.viewer-nav svg {
    height: 1.35rem;
    width: 1.35rem;
}

@media (min-width: 640px) {
    .viewer-nav {
        display: grid;
    }
}

.viewer-prev {
    left: 0.9rem;
}

.viewer-next {
    right: 0.9rem;
}

.viewer-nav[hidden] {
    display: none;
}

.viewer-state {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.75rem;
    padding: 1.5rem;
    font-size: 0.875rem;
    text-align: center;
    pointer-events: none;
}

.viewer-state[hidden] {
    display: none;
}

.viewer-state .btn {
    pointer-events: auto;
}

.viewer-strip {
    display: flex;
    gap: 0.4rem;
    overflow-x: auto;
    padding: 0.55rem 0.75rem;
    padding-bottom: max(0.75rem, env(safe-area-inset-bottom));
    scrollbar-width: none;
}

.viewer-strip::-webkit-scrollbar {
    display: none;
}

.viewer-strip-inner {
    display: flex;
    gap: 0.4rem;
    margin: 0 auto;
}

.viewer-thumb {
    height: 3.125rem;
    width: 3.125rem;
    flex: none;
    overflow: hidden;
    border: 2px solid transparent;
    border-radius: 0.5rem;
    background: hsl(var(--viewer-foreground) / 0.08);
    opacity: 0.5;
    cursor: pointer;
    transition:
        opacity 0.14s ease,
        border-color 0.14s ease;
}

.viewer-thumb:hover {
    opacity: 0.85;
}

.viewer-thumb[aria-current='true'] {
    border-color: hsl(var(--viewer-foreground));
    opacity: 1;
}

.viewer-thumb img {
    height: 100%;
    width: 100%;
    object-fit: cover;
}

/* --------------------------------------------------------------------------
   18. Motion
   -------------------------------------------------------------------------- */

.spin {
    animation: spin 0.8s linear infinite;
}

.pulse-dot {
    animation: pulse-dot 1.1s ease-in-out infinite;
}

.task.is-new {
    animation: task-in 0.24s ease-out;
}

/* A task that just changed in another tab or device lights up briefly. */
.task.is-updated {
    animation: task-flash 1.6s ease-out;
}

@keyframes task-flash {
    from {
        border-color: hsl(var(--primary) / 0.55);
        box-shadow:
            0 0 0 4px hsl(var(--primary) / 0.14),
            var(--shadow);
    }
}

@keyframes spin {
    to {
        transform: rotate(360deg);
    }
}

@keyframes pulse-dot {
    0%,
    100% {
        opacity: 1;
    }
    50% {
        opacity: 0.3;
    }
}

@keyframes task-in {
    from {
        opacity: 0;
        transform: translateY(-4px);
    }
    to {
        opacity: 1;
        transform: none;
    }
}

@keyframes pop-in {
    from {
        opacity: 0;
        transform: translateY(-4px) scale(0.98);
    }
    to {
        opacity: 1;
        transform: none;
    }
}

@keyframes toast-in {
    from {
        opacity: 0;
        transform: translateY(8px);
    }
    to {
        opacity: 1;
        transform: none;
    }
}

@keyframes toast-out {
    to {
        opacity: 0;
        transform: translateY(6px);
    }
}

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

@keyframes sheet-in {
    from {
        opacity: 0;
        transform: translateY(10px);
    }
    to {
        opacity: 1;
        transform: none;
    }
}

@media (prefers-reduced-motion: reduce) {
    .toast,
    .dialog-panel,
    .dialog-backdrop,
    .viewer,
    .menu,
    .task.is-new,
    .task.is-updated,
    .pulse-dot {
        animation: none;
    }

    .spin {
        animation-duration: 2.4s;
    }

    .viewer-img.is-smooth,
    .thumb-open img,
    .progress-bar,
    .btn {
        transition: none;
    }
}

/* --------------------------------------------------------------------------
   19. Touch screens
   On a phone or tablet every button is at least about 44 pixels, so it is
   easy to hit with a finger.
   -------------------------------------------------------------------------- */

@media (pointer: coarse) {
    .btn,
    .btn-subtle,
    .tab {
        height: 2.75rem;
    }

    .btn-sm {
        height: 2.5rem;
    }

    .icon-btn {
        height: 2.75rem;
        width: 2.75rem;
    }

    .chip .icon-btn {
        height: 2.5rem;
        width: 2.5rem;
    }

    .app-chip,
    .apps .app-chip {
        min-height: 2.5rem;
    }

    .status-pill,
    .app-tag {
        position: relative;
        height: 2rem;
    }

    .status-pill::after,
    .app-tag::after {
        content: '';
        position: absolute;
        inset: -0.4rem -0.2rem;
    }

    .thumb-remove {
        height: 2.25rem;
        width: 2.25rem;
    }

    .menu-item {
        height: 2.875rem;
    }

    .toast-action {
        min-height: 2.75rem;
        padding: 0 0.5rem;
    }

    .viewer-btn {
        height: 2.875rem;
        width: 2.875rem;
    }

    .viewer-thumb {
        height: 3.5rem;
        width: 3.5rem;
    }
}

/* --------------------------------------------------------------------------
   20. High contrast
   When the system replaces the colours, whatever is chosen or pressed
   still stands out with an outline, and the coloured dots keep a border.
   -------------------------------------------------------------------------- */

@media (forced-colors: active) {
    .tab[aria-pressed='true'],
    .app-chip[aria-pressed='true'],
    .viewer-thumb[aria-current='true'] {
        outline: 2px solid Highlight;
        outline-offset: 1px;
    }

    .app-dot,
    .status-pill .dot,
    .add-status .dot {
        forced-color-adjust: none;
        border: 1px solid CanvasText;
    }

    .color-pick label {
        forced-color-adjust: none;
        border: 2px solid CanvasText;
    }

    .task::before,
    .progress-bar {
        background: Highlight;
    }

    .toast,
    .menu,
    .dialog-panel {
        border: 1px solid CanvasText;
    }
}

/* --------------------------------------------------------------------------
   21. Editing in place
   The text of a task turns into a box right where it is.
   -------------------------------------------------------------------------- */

.task.is-inline {
    border-color: hsl(var(--primary) / 0.55);
    box-shadow:
        0 0 0 4px hsl(var(--primary) / 0.08),
        var(--shadow);
}

.inline-edit {
    margin: -0.3rem -0.4rem 0;
}

.inline-field {
    display: block;
    width: 100%;
    min-height: 2.25rem;
    padding: 0.35rem 0.5rem;
    border: 1px solid hsl(var(--primary) / 0.6);
    border-radius: 0.5rem;
    background: hsl(var(--card));
    font-size: 0.9375rem;
    line-height: 1.45rem;
    color: hsl(var(--foreground));
    resize: none;
    overflow-y: hidden;
    user-select: text;
    -webkit-user-select: text;
    box-shadow: 0 0 0 3px hsl(var(--primary) / 0.22);
}

.inline-field:focus,
.inline-field:focus-visible {
    outline: none;
    border-color: hsl(var(--primary));
    box-shadow: 0 0 0 3px hsl(var(--primary) / 0.32);
}

.inline-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem;
    margin-top: 0.45rem;
}

.inline-hint {
    margin-right: auto;
}

@media (hover: none) {
    .inline-hint {
        display: none;
    }

    .inline-bar {
        justify-content: flex-end;
    }
}

/* --------------------------------------------------------------------------
   22. Putting tasks in order
   Every task has a grip. While a task is carried its place stays dashed in
   the list, and the apps and status tabs it can land on are outlined.
   -------------------------------------------------------------------------- */

.task {
    user-select: none;
    -webkit-user-select: none;
}

.task img {
    -webkit-user-drag: none;
}

.task-list {
    position: relative;
}

.drag-handle {
    position: relative;
    display: inline-flex;
    flex: none;
    align-items: center;
    justify-content: center;
    height: 1.75rem;
    width: 1.125rem;
    margin: -0.05rem -0.35rem 0 -0.45rem;
    border-radius: 0.4rem;
    color: hsl(var(--muted-foreground));
    opacity: 0.45;
    cursor: grab;
    touch-action: none;
    -webkit-touch-callout: none;
    transition:
        opacity 0.14s ease,
        background-color 0.14s ease,
        color 0.14s ease;
}

.drag-handle::after {
    content: '';
    position: absolute;
    inset: -0.4rem -0.3rem;
}

.task:hover .drag-handle,
.drag-handle:focus-visible {
    opacity: 1;
}

.drag-handle:hover {
    background: hsl(var(--muted));
    color: hsl(var(--foreground));
}

.task.is-dragging {
    border-style: dashed;
    border-color: hsl(var(--primary) / 0.6);
    background: hsl(var(--primary) / 0.04);
    box-shadow: none;
}

.task.is-dragging > *,
.task.is-dragging::before {
    opacity: 0.18;
}

.drag-ghost {
    position: fixed;
    top: 0;
    left: 0;
    z-index: 75;
    margin: 0;
    list-style: none;
    pointer-events: none;
    border-color: hsl(var(--primary) / 0.5);
    box-shadow:
        0 22px 44px -16px hsl(var(--foreground) / 0.4),
        0 0 0 1px hsl(var(--primary) / 0.15);
    will-change: transform;
}

.drag-ghost .drag-handle {
    opacity: 1;
    color: hsl(var(--primary));
}

html.is-sorting,
html.is-sorting * {
    cursor: grabbing !important;
    user-select: none !important;
    -webkit-user-select: none !important;
}

html.is-sorting .app-chip:not([data-app='all']),
html.is-sorting .tab:not([data-view='all']) {
    outline: 1.5px dashed hsl(var(--primary) / 0.45);
    outline-offset: 2px;
}

.app-chip.is-drop,
.tab.is-drop {
    outline: 2px solid hsl(var(--primary)) !important;
    outline-offset: 2px;
    background: hsl(var(--primary) / 0.12);
    color: hsl(var(--primary));
}

/* The small menus of a task. */
.menu-sep {
    height: 1px;
    margin: 0.3rem 0.35rem;
    background: hsl(var(--border));
}

.menu-item.menu-extra > svg:first-child {
    color: hsl(var(--muted-foreground));
}

.menu-item .app-dot {
    margin: 0 0.25rem;
}

.app-dot-none {
    background: transparent;
    border: 1.5px dashed hsl(var(--muted-foreground));
}

@media (pointer: coarse) {
    .drag-handle {
        height: 2.75rem;
        width: 1.75rem;
        margin: -0.55rem -0.45rem -0.55rem -0.6rem;
        opacity: 0.7;
    }
}

@media (prefers-reduced-motion: reduce) {
    .drag-handle {
        transition: none;
    }
}

@media (forced-colors: active) {
    .app-chip.is-drop,
    .tab.is-drop {
        outline: 3px solid Highlight !important;
    }

    .drag-ghost,
    .task.is-dragging {
        border: 2px dashed CanvasText;
    }

    .app-dot-none {
        border-color: CanvasText;
    }
}

/* --------------------------------------------------------------------------
   23. Signing in
   A large email field, the 6-digit code in wide mono type, and quiet text
   buttons to send the code again or change the email.
   -------------------------------------------------------------------------- */

.field-lg {
    height: 3rem;
    font-size: 1rem;
}

.btn-lg {
    height: 3rem;
    font-size: 0.9375rem;
}

.code-field {
    height: 3.5rem;
    padding-left: 1.1rem;
    font-family: 'DM Mono', ui-monospace, SFMono-Regular, monospace;
    font-size: 1.625rem;
    font-weight: 500;
    letter-spacing: 0.55em;
    text-align: center;
}

.code-field::placeholder {
    color: hsl(var(--muted-foreground) / 0.4);
}

.field[aria-invalid='true'] {
    border-color: hsl(var(--danger));
}

.field[aria-invalid='true']:focus {
    box-shadow: 0 0 0 3px hsl(var(--danger) / 0.25);
}

.link-btn {
    display: inline-flex;
    align-items: center;
    min-height: 2.25rem;
    padding: 0 0.3rem;
    border-radius: 0.4rem;
    font-size: 0.8125rem;
    font-weight: 600;
    color: hsl(var(--primary));
    cursor: pointer;
}

.link-btn:hover:not(:disabled) {
    text-decoration: underline;
    text-underline-offset: 3px;
}

.link-btn:disabled {
    font-weight: 500;
    color: hsl(var(--muted-foreground));
    cursor: default;
}

/* The page settles in gently; without motion it is simply there. */
.auth-reveal {
    animation: auth-in 0.4s ease-out backwards;
}

.auth-reveal-late {
    animation-delay: 0.08s;
}

@keyframes auth-in {
    from {
        opacity: 0;
        transform: translateY(8px);
    }
}

@media (prefers-reduced-motion: reduce) {
    .auth-reveal {
        animation: none;
    }
}

@media (pointer: coarse) {
    .btn-lg {
        height: 3rem;
    }

    .link-btn {
        min-height: 2.75rem;
    }
}

/* --------------------------------------------------------------------------
   24. The board
   Three trays side by side, one for each status, with the cards on them.
   On a phone the trays slide sideways one at a time; from a laptop up all
   three sit next to each other.
   -------------------------------------------------------------------------- */

.kanban {
    position: relative;
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 86%);
    gap: 0.75rem;
    align-items: start;
    margin: 0 -1rem;
    padding: 0.25rem 1rem 1rem;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;
    scroll-padding: 0 1rem;
    scrollbar-width: thin;
}

.kanban > .column {
    scroll-snap-align: start;
}

@media (min-width: 640px) {
    .kanban {
        grid-auto-columns: minmax(0, 58%);
    }
}

@media (min-width: 1024px) {
    .kanban {
        grid-auto-flow: row;
        grid-template-columns: repeat(3, minmax(0, 1fr));
        gap: 1rem;
        margin: 0;
        padding: 0.25rem 0 1rem;
        overflow: visible;
        scroll-snap-type: none;
    }
}

/* One status on its own, as a single wider tray. */
.kanban.is-single {
    grid-auto-flow: row;
    grid-template-columns: minmax(0, 1fr);
    max-width: 48rem;
    margin: 0;
    padding: 0.25rem 0 1rem;
    overflow: visible;
    scroll-snap-type: none;
}

html.is-sorting .kanban {
    scroll-snap-type: none;
    scroll-behavior: auto;
}

.column {
    --st: var(--primary);
    --st-ink: var(--primary);
    position: relative;
    display: flex;
    flex-direction: column;
    min-width: 0;
    padding: 0.5rem 0.5rem 0.6rem;
    border: 1px solid hsl(var(--border));
    border-radius: calc(var(--radius) + 0.25rem);
    background: hsl(var(--muted) / 0.75);
    transition:
        background-color 0.16s ease,
        border-color 0.16s ease;
}

/* The colour of the status runs along the top of its tray. */
.column::before {
    content: '';
    position: absolute;
    top: -1px;
    left: 1rem;
    right: 1rem;
    height: 3px;
    border-radius: 0 0 3px 3px;
    background: hsl(var(--st));
}

.column-head {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.35rem 0.1rem 0.55rem 0.4rem;
}

.column-title {
    display: flex;
    flex: 1;
    min-width: 0;
    align-items: center;
    gap: 0.5rem;
    margin: 0;
    font-size: 0.875rem;
    font-weight: 600;
    letter-spacing: 0;
    color: hsl(var(--st-ink));
}

.column-title svg {
    flex: none;
    height: 1rem;
    width: 1rem;
    color: hsl(var(--st));
}

.column-add {
    height: 1.875rem;
    width: 1.875rem;
}

.column-add:hover {
    background: hsl(var(--st) / 0.14);
    color: hsl(var(--st-ink));
}

.column .task-list {
    min-height: 5.5rem;
    align-content: start;
}

/* An empty tray still shows where a card can be dropped. */
.column .task-list:empty {
    place-items: center;
    border: 1.5px dashed hsl(var(--border));
    border-radius: var(--radius);
}

.column .task-list:empty::before {
    content: 'Asnjë detyrë këtu';
    font-size: 0.8125rem;
    color: hsl(var(--muted-foreground));
}

/* The tray a carried card is about to land in lights up. */
html.is-sorting .column:has(.task.is-dragging) {
    background: hsl(var(--st) / 0.09);
    border-color: hsl(var(--st) / 0.45);
}

/* The buttons of a card sit in its bottom line; on a computer they show
   when the card is pointed at or reached with the keyboard. */
.task-tools {
    display: flex;
    align-items: center;
    gap: 0.05rem;
    margin: -0.2rem -0.35rem -0.2rem auto;
}

.task-tools .icon-btn {
    height: 1.875rem;
    width: 1.875rem;
}

@media (hover: hover) {
    .task-tools {
        opacity: 0;
        transition: opacity 0.14s ease;
    }

    .task:hover .task-tools,
    .task:focus-within .task-tools {
        opacity: 1;
    }
}

/* The status line in the composer opens a small menu. */
button.add-status {
    height: 2rem;
    padding: 0 0.45rem;
    border-radius: 0.5rem;
    cursor: pointer;
    transition:
        background-color 0.14s ease,
        color 0.14s ease;
}

button.add-status:hover,
button.add-status[aria-expanded='true'] {
    background: hsl(var(--muted));
    color: hsl(var(--foreground));
}

.add-status .add-chev {
    height: 0.8rem;
    width: 0.8rem;
    opacity: 0.7;
}

/* --------------------------------------------------------------------------
   25. Choosing several tasks
   Every card has a small box at its right. It shows when the card is
   pointed at, and on every card while choosing is on.
   -------------------------------------------------------------------------- */

.select-box {
    position: relative;
    display: inline-grid;
    flex: none;
    place-items: center;
    height: 1.375rem;
    width: 1.375rem;
    margin: 0.12rem -0.1rem 0 0;
    border: 1.5px solid hsl(var(--muted-foreground) / 0.45);
    border-radius: 0.4rem;
    background: hsl(var(--card));
    color: hsl(var(--primary-foreground));
    cursor: pointer;
    opacity: 0;
    transition:
        opacity 0.14s ease,
        background-color 0.14s ease,
        border-color 0.14s ease;
}

.select-box::after {
    content: '';
    position: absolute;
    inset: -0.5rem;
}

.select-box svg {
    height: 0.85rem;
    width: 0.85rem;
    opacity: 0;
}

.task:hover .select-box,
.select-box:focus-visible,
.is-selecting .select-box,
.task.is-selected .select-box {
    opacity: 1;
}

.select-box:hover {
    border-color: hsl(var(--primary));
}

.task.is-selected .select-box {
    border-color: hsl(var(--primary));
    background: hsl(var(--primary));
}

.task.is-selected .select-box svg {
    opacity: 1;
}

.task.is-selected {
    border-color: hsl(var(--primary) / 0.7);
    background:
        linear-gradient(hsl(var(--primary) / 0.05), hsl(var(--primary) / 0.05)),
        hsl(var(--card));
    box-shadow:
        0 0 0 1px hsl(var(--primary) / 0.55),
        var(--shadow);
}

.is-selecting .task,
.is-selecting .task-text {
    cursor: pointer;
}

@media (hover: none) {
    .select-box {
        display: none;
    }

    .is-selecting .select-box,
    .task.is-selected .select-box {
        display: inline-grid;
    }
}

@media (pointer: coarse) {
    .select-box {
        height: 1.625rem;
        width: 1.625rem;
    }

    .task-tools .icon-btn {
        height: 2.5rem;
        width: 2.5rem;
    }

    .column-add {
        height: 2.5rem;
        width: 2.5rem;
    }

    button.add-status {
        height: 2.75rem;
    }
}

/* Cards that travel with the one being dragged wait out of sight. */
.task.is-carried {
    display: none;
}

/* Several cards carried together look like a small stack with a count. */
.drag-ghost.is-stack {
    box-shadow:
        5px 5px 0 -1px hsl(var(--card)),
        5px 5px 0 0 hsl(var(--border)),
        10px 10px 0 -1px hsl(var(--card)),
        10px 10px 0 0 hsl(var(--border)),
        0 22px 44px -16px hsl(var(--foreground) / 0.4);
}

.drag-count {
    position: absolute;
    top: -0.6rem;
    right: -0.6rem;
    display: grid;
    place-items: center;
    min-width: 1.6rem;
    height: 1.6rem;
    padding: 0 0.4rem;
    border-radius: 999px;
    background: hsl(var(--primary));
    color: hsl(var(--primary-foreground));
    font-family: 'DM Mono', ui-monospace, SFMono-Regular, monospace;
    font-size: 0.75rem;
    font-weight: 500;
    box-shadow: 0 4px 10px -2px hsl(var(--primary) / 0.5);
}

/* --------------------------------------------------------------------------
   26. The action bar
   A light bar that floats at the bottom while tasks are chosen, made like
   the cards: how many are chosen, and what to do with all of them at once.
   -------------------------------------------------------------------------- */

.bulk {
    position: fixed;
    left: 0;
    right: 0;
    bottom: max(0.75rem, env(safe-area-inset-bottom));
    z-index: 70;
    display: flex;
    justify-content: center;
    padding: 0 0.75rem;
    pointer-events: none;
    animation: bulk-in 0.2s ease-out;
}

.bulk-inner {
    display: flex;
    max-width: 100%;
    align-items: center;
    gap: 0.15rem;
    padding: 0.35rem;
    border: 1px solid hsl(var(--border));
    border-radius: 1.1rem;
    background: hsl(var(--card) / 0.94);
    color: hsl(var(--foreground));
    -webkit-backdrop-filter: blur(16px) saturate(1.5);
    backdrop-filter: blur(16px) saturate(1.5);
    box-shadow:
        0 1px 2px hsl(var(--foreground) / 0.05),
        0 24px 50px -20px hsl(var(--foreground) / 0.32),
        0 0 0 4px hsl(var(--primary) / 0.07);
    pointer-events: auto;
}

/* How many are chosen, in a soft indigo pill. */
.bulk-count {
    display: flex;
    flex: none;
    align-items: center;
    gap: 0.5rem;
    height: 2.25rem;
    padding: 0 0.75rem 0 0.3rem;
    border-radius: 0.75rem;
    background: hsl(var(--primary) / 0.08);
    font-size: 0.8125rem;
    font-weight: 600;
    white-space: nowrap;
    color: hsl(var(--accent));
}

.bulk-count b {
    display: grid;
    place-items: center;
    min-width: 1.6rem;
    height: 1.6rem;
    padding: 0 0.4rem;
    border-radius: 999px;
    background: hsl(var(--primary));
    color: hsl(var(--primary-foreground));
    font-family: 'DM Mono', ui-monospace, SFMono-Regular, monospace;
    font-size: 0.75rem;
    font-weight: 500;
    box-shadow: 0 3px 8px -3px hsl(var(--primary) / 0.7);
}

.bulk-sep {
    flex: none;
    width: 1px;
    height: 1.25rem;
    margin: 0 0.25rem;
    background: hsl(var(--border));
}

.bulk-btn {
    display: inline-flex;
    flex: none;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    height: 2.25rem;
    min-width: 2.25rem;
    padding: 0 0.6rem;
    border-radius: 0.6rem;
    font-size: 0.8125rem;
    font-weight: 500;
    white-space: nowrap;
    color: hsl(var(--foreground) / 0.85);
    cursor: pointer;
    transition:
        background-color 0.14s ease,
        color 0.14s ease;
}

.bulk-btn svg {
    flex: none;
    height: 1rem;
    width: 1rem;
    color: hsl(var(--muted-foreground));
    transition: color 0.14s ease;
}

.bulk-btn:hover:not(:disabled),
.bulk-btn[aria-expanded='true'] {
    background: hsl(var(--muted));
    color: hsl(var(--foreground));
}

.bulk-btn:hover:not(:disabled) svg,
.bulk-btn[aria-expanded='true'] svg {
    color: hsl(var(--primary));
}

.bulk-danger,
.bulk-danger svg,
.bulk-danger:hover:not(:disabled) svg {
    color: hsl(var(--danger));
}

.bulk-danger:hover:not(:disabled) {
    background: hsl(var(--danger) / 0.09);
    color: hsl(var(--danger));
}

.bulk-btn:disabled {
    opacity: 0.4;
    cursor: default;
}

.bulk-label {
    display: none;
}

@media (min-width: 640px) {
    .bulk-label {
        display: inline;
    }

    .bulk-btn {
        padding: 0 0.7rem;
    }
}

@keyframes bulk-in {
    from {
        opacity: 0;
        transform: translateY(12px);
    }
}

/* On a phone the notices rise above the bar. */
@media (max-width: 639px) {
    html.has-bulk #toasts {
        bottom: 4.5rem;
    }
}

@media (pointer: coarse) {
    .bulk-btn {
        height: 2.75rem;
        min-width: 2.75rem;
    }
}

@media (prefers-reduced-motion: reduce) {
    .bulk,
    .column,
    .select-box,
    .task-tools {
        animation: none;
        transition: none;
    }
}

@media (forced-colors: active) {
    .task.is-selected {
        outline: 3px solid Highlight;
    }

    .select-box {
        forced-color-adjust: none;
        border: 2px solid CanvasText;
    }

    .task.is-selected .select-box {
        background: Highlight;
    }

    .bulk-inner,
    .column {
        border: 1px solid CanvasText;
    }
}

/* --------------------------------------------------------------------------
   27. A card in full
   A panel that slides in from the right on a computer and rises from the
   bottom on a phone: the whole text, the status, the app, the files, or
   the same choices for every chosen card at once.
   -------------------------------------------------------------------------- */

html.has-panel,
html.has-panel body {
    overflow: hidden;
}

.panel-backdrop {
    position: fixed;
    inset: 0;
    z-index: 76;
    background: hsl(var(--foreground) / 0.32);
    -webkit-backdrop-filter: blur(2px);
    backdrop-filter: blur(2px);
    animation: fade-in 0.16s ease-out;
}

.panel {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 77;
    display: flex;
    flex-direction: column;
    max-height: 92dvh;
    border: 1px solid hsl(var(--border));
    border-radius: 1.15rem 1.15rem 0 0;
    background: hsl(var(--card));
    box-shadow: 0 -24px 60px -24px hsl(var(--foreground) / 0.45);
    animation: sheet-in 0.22s cubic-bezier(0.2, 0.8, 0.2, 1);
}

.panel:focus {
    outline: none;
}

@media (min-width: 768px) {
    .panel {
        top: 0.75rem;
        right: 0.75rem;
        bottom: 0.75rem;
        left: auto;
        width: min(31rem, calc(100vw - 1.5rem));
        max-height: none;
        border-radius: 1.15rem;
        box-shadow: 0 30px 80px -30px hsl(var(--foreground) / 0.5);
        animation: panel-in 0.24s cubic-bezier(0.2, 0.8, 0.2, 1);
    }
}

.panel.is-dropping {
    border-color: hsl(var(--primary));
    box-shadow:
        0 0 0 4px hsl(var(--primary) / 0.2),
        0 30px 80px -30px hsl(var(--foreground) / 0.5);
}

.panel-head {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.8rem 0.75rem 0.8rem 1.25rem;
    border-bottom: 1px solid hsl(var(--border));
}

.panel-head > .icon-btn:first-child {
    margin-left: -0.6rem;
}

.panel-title {
    margin-top: 0.1rem;
    overflow: hidden;
    font-size: 1.0625rem;
    font-weight: 600;
    letter-spacing: -0.01em;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.panel-body {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: 1.15rem 1.25rem 1.5rem;
}

.panel-dyn {
    display: grid;
    gap: 1.4rem;
}

.panel-text-wrap {
    margin-bottom: 1.4rem;
}

.panel-text {
    min-height: 7rem;
    padding: 0.7rem 0.85rem;
    border-radius: 0.75rem;
    font-size: 1rem;
    line-height: 1.6rem;
}

.panel-text-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    min-height: 2.125rem;
    margin-top: 0.45rem;
}

.panel-text-read {
    margin-bottom: 1.4rem;
    padding: 0.8rem 0.9rem;
    border-radius: 0.75rem;
    background: hsl(var(--muted) / 0.7);
    font-size: 1rem;
    line-height: 1.6rem;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
    color: hsl(var(--muted-foreground));
}

.panel-label {
    margin: 0 0 0.55rem;
    font-family: 'DM Mono', ui-monospace, SFMono-Regular, monospace;
    font-size: 0.6875rem;
    font-weight: 500;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: hsl(var(--muted-foreground));
}

/* The three statuses side by side, the current one raised. */
.seg {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 0.3rem;
    padding: 0.3rem;
    border-radius: 0.85rem;
    background: hsl(var(--muted));
}

.seg-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    min-width: 0;
    height: 2.5rem;
    padding: 0 0.5rem;
    border-radius: 0.6rem;
    font-size: 0.8125rem;
    font-weight: 600;
    white-space: nowrap;
    color: hsl(var(--muted-foreground));
    cursor: pointer;
    transition:
        background-color 0.14s ease,
        color 0.14s ease,
        box-shadow 0.14s ease;
}

.seg-btn svg {
    flex: none;
    height: 1rem;
    width: 1rem;
    color: hsl(var(--st));
}

.seg-btn:hover {
    background: hsl(var(--card) / 0.6);
    color: hsl(var(--foreground));
}

.seg-btn[aria-pressed='true'] {
    background: hsl(var(--card));
    color: hsl(var(--st-ink));
    box-shadow:
        0 1px 2px hsl(var(--foreground) / 0.08),
        inset 0 0 0 1.5px hsl(var(--st) / 0.55);
}

.pick {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
}

.panel-files > * + * {
    margin-top: 0.6rem;
}

.panel-files .thumbs,
.panel-files .files {
    margin-top: 0;
}

.panel-add-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
}

.panel-empty {
    padding: 0.9rem;
    border: 1.5px dashed hsl(var(--border));
    border-radius: 0.75rem;
    font-size: 0.8125rem;
    text-align: center;
    color: hsl(var(--muted-foreground));
}

.panel-list {
    display: grid;
    gap: 0.35rem;
}

.panel-item {
    display: flex;
    width: 100%;
    align-items: center;
    gap: 0.6rem;
    min-height: 2.75rem;
    padding: 0.45rem 0.7rem;
    border: 1px solid hsl(var(--border));
    border-radius: 0.65rem;
    background: hsl(var(--card));
    font-size: 0.875rem;
    text-align: left;
    cursor: pointer;
    transition:
        border-color 0.14s ease,
        background-color 0.14s ease;
}

.panel-item:hover {
    border-color: hsl(var(--primary) / 0.45);
    background: hsl(var(--primary) / 0.04);
}

.panel-item > svg:first-child {
    flex: none;
    height: 1rem;
    width: 1rem;
    color: hsl(var(--st));
}

.panel-item-text {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.panel-note {
    padding: 0.65rem 0.8rem;
    border-left: 3px solid hsl(var(--warning));
    border-radius: 0.5rem;
    background: hsl(var(--warning) / 0.08);
    font-size: 0.8125rem;
    line-height: 1.45;
}

.panel-meta {
    font-size: 0.75rem;
    color: hsl(var(--muted-foreground));
}

.panel-foot {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    padding: 0.75rem 1.25rem;
    padding-bottom: max(0.75rem, env(safe-area-inset-bottom));
    border-top: 1px solid hsl(var(--border));
    background: hsl(var(--muted) / 0.45);
}

@media (min-width: 768px) {
    .panel-foot {
        border-radius: 0 0 1.15rem 1.15rem;
    }
}

@keyframes panel-in {
    from {
        opacity: 0;
        transform: translateX(24px);
    }
}

@media (prefers-reduced-motion: reduce) {
    .panel,
    .panel-backdrop {
        animation: none;
    }

    .seg-btn,
    .panel-item {
        transition: none;
    }
}

@media (pointer: coarse) {
    .seg-btn {
        height: 2.75rem;
    }
}

@media (forced-colors: active) {
    .panel {
        border: 1px solid CanvasText;
    }

    .seg-btn[aria-pressed='true'] {
        outline: 2px solid Highlight;
    }
}

/* --------------------------------------------------------------------------
   28. The sign-in page
   A dark showcase with a small living board on the left, the sign-in card
   on a dotted desk on the right. On a phone only the card shows.
   -------------------------------------------------------------------------- */

.auth-shell {
    display: grid;
    flex: 1;
    min-height: 100dvh;
}

@media (min-width: 1024px) {
    .auth-shell {
        grid-template-columns: minmax(0, 1.08fr) minmax(0, 1fr);
    }
}

.auth-show {
    --glow: 243 100% 80%;
    position: relative;
    display: none;
    flex-direction: column;
    justify-content: space-between;
    gap: 2.5rem;
    overflow: hidden;
    padding: 2.5rem 3rem 2.75rem;
    background: hsl(var(--foreground));
    color: hsl(var(--card));
}

@media (min-width: 1024px) {
    .auth-show {
        display: flex;
    }
}

/* Two soft glows behind everything. */
.auth-show::before,
.auth-show::after {
    content: '';
    position: absolute;
    border-radius: 999px;
    filter: blur(70px);
    pointer-events: none;
}

.auth-show::before {
    top: -9rem;
    right: -7rem;
    height: 25rem;
    width: 25rem;
    background: hsl(var(--primary) / 0.55);
}

.auth-show::after {
    bottom: -11rem;
    left: -9rem;
    height: 22rem;
    width: 22rem;
    background: hsl(var(--done) / 0.22);
}

.auth-show > * {
    position: relative;
    z-index: 1;
}

.auth-brand {
    display: inline-flex;
    align-items: center;
    gap: 0.65rem;
    font-size: 1.0625rem;
    font-weight: 700;
    letter-spacing: -0.01em;
}

.auth-brand img {
    height: 2rem;
    width: 2rem;
    padding: 0.25rem;
    border-radius: 0.6rem;
    background: hsl(var(--card));
}

.auth-kicker {
    font-family: 'DM Mono', ui-monospace, SFMono-Regular, monospace;
    font-size: 0.75rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: hsl(var(--card) / 0.6);
}

.auth-title {
    max-width: 30rem;
    margin-top: 0.9rem;
    font-size: clamp(2.25rem, 3.4vw, 3.25rem);
    font-weight: 700;
    line-height: 1.04;
    letter-spacing: -0.035em;
}

.auth-title em {
    font-style: normal;
    color: hsl(var(--glow));
}

.auth-sub {
    max-width: 28rem;
    margin-top: 1rem;
    font-size: 1rem;
    line-height: 1.65;
    color: hsl(var(--card) / 0.72);
}

/* The small board: three trays with cards, one of them being carried. */
.mini-board {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 0.7rem;
    max-width: 34rem;
    padding: 0.85rem;
    border: 1px solid hsl(var(--card) / 0.12);
    border-radius: 1.15rem;
    background: hsl(var(--card) / 0.05);
    box-shadow:
        0 30px 60px -30px hsl(var(--foreground) / 0.9),
        inset 0 1px 0 hsl(var(--card) / 0.08);
}

.mini-col {
    display: grid;
    align-content: start;
    gap: 0.5rem;
    padding: 0.55rem;
    border-radius: 0.8rem;
    background: hsl(var(--card) / 0.06);
}

.mini-head {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.1rem 0.15rem 0.25rem;
    font-size: 0.6875rem;
    font-weight: 600;
    color: hsl(var(--card) / 0.85);
}

.mini-head i {
    height: 0.45rem;
    width: 0.45rem;
    border-radius: 999px;
    background: hsl(var(--st));
}

.mini-head b {
    margin-left: auto;
    font-family: 'DM Mono', ui-monospace, SFMono-Regular, monospace;
    font-weight: 500;
    color: hsl(var(--card) / 0.5);
}

.mini-card {
    position: relative;
    display: grid;
    gap: 0.35rem;
    padding: 0.6rem;
    border-radius: 0.6rem;
    background: hsl(var(--card));
    box-shadow: 0 6px 14px -8px hsl(var(--foreground) / 0.8);
}

.mini-line {
    display: block;
    height: 0.4rem;
    border-radius: 999px;
    background: hsl(var(--foreground) / 0.14);
}

.mini-line.is-mid {
    width: 78%;
}

.mini-line.is-short {
    width: 52%;
}

.st-completed .mini-line {
    background: hsl(var(--foreground) / 0.08);
}

.mini-foot {
    display: flex;
    align-items: center;
    gap: 0.3rem;
    margin-top: 0.15rem;
}

.mini-dot {
    height: 0.6rem;
    width: 0.6rem;
    border-radius: 0.2rem;
    background: hsl(var(--app));
}

.mini-chip {
    height: 0.75rem;
    width: 2.1rem;
    border-radius: 999px;
    background: hsl(var(--app) / 0.2);
}

.mini-check {
    height: 0.85rem;
    width: 0.85rem;
    margin-left: auto;
    color: hsl(var(--done));
}

/* A card chosen among several. */
.mini-card.is-picked {
    box-shadow:
        0 0 0 2px hsl(var(--glow)),
        0 6px 14px -8px hsl(var(--foreground) / 0.8);
}

/* The card being carried rises, tilts and settles, again and again. */
.mini-card.is-lift {
    z-index: 2;
    animation: mini-lift 4.8s ease-in-out infinite;
}

.mini-cursor {
    position: absolute;
    right: -0.45rem;
    bottom: -0.7rem;
    height: 1.35rem;
    width: 1.35rem;
    color: hsl(var(--card));
    filter: drop-shadow(0 2px 3px hsl(var(--foreground) / 0.6));
}

@keyframes mini-lift {
    0%,
    18%,
    100% {
        transform: none;
        box-shadow: 0 6px 14px -8px hsl(var(--foreground) / 0.8);
    }
    40%,
    62% {
        transform: translate(10px, -8px) rotate(2.5deg);
        box-shadow: 0 22px 34px -14px hsl(var(--foreground) / 0.95);
    }
}

.auth-proof {
    display: flex;
    flex-wrap: wrap;
    gap: 0.6rem 1.5rem;
    font-size: 0.8125rem;
    color: hsl(var(--card) / 0.72);
}

.auth-proof li {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
}

.auth-proof svg {
    height: 1rem;
    width: 1rem;
    color: hsl(var(--glow));
}

/* The side with the card. */
.auth-side {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1.25rem;
    padding: 1.5rem 1rem 2rem;
    background-color: hsl(var(--background));
    background-image: radial-gradient(hsl(var(--border)) 1px, transparent 1px);
    background-size: 22px 22px;
}

@media (min-width: 640px) {
    .auth-side {
        padding: 2.5rem 2rem;
    }
}

.auth-top,
.auth-card,
.auth-foot {
    width: 100%;
    max-width: 26.5rem;
}

.auth-card {
    padding: 1.75rem 1.5rem 1.5rem;
    border: 1px solid hsl(var(--border));
    border-radius: 1.4rem;
    background: hsl(var(--card));
    box-shadow:
        0 1px 2px hsl(var(--foreground) / 0.04),
        0 24px 60px -28px hsl(var(--foreground) / 0.28);
}

@media (min-width: 640px) {
    .auth-card {
        padding: 2.25rem 2.25rem 2rem;
    }
}

.auth-badge {
    display: grid;
    place-items: center;
    height: 3rem;
    width: 3rem;
    border-radius: 0.95rem;
    background: hsl(var(--primary) / 0.1);
    color: hsl(var(--primary));
}

.auth-badge svg {
    height: 1.4rem;
    width: 1.4rem;
}

/* An envelope while typing the email, an inbox while waiting for the code. */
.auth-badge .is-code,
[data-step='code'] .auth-badge .is-email {
    display: none;
}

[data-step='code'] .auth-badge .is-code {
    display: block;
}

.auth-progress {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

.auth-progress-bar {
    position: relative;
    flex: 1;
    height: 0.25rem;
    overflow: hidden;
    border-radius: 999px;
    background: hsl(var(--muted));
}

.auth-progress-bar::after {
    content: '';
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    width: 50%;
    border-radius: inherit;
    background: hsl(var(--primary));
    transition: width 0.35s ease;
}

[data-step='code'] .auth-progress-bar::after {
    width: 100%;
}

.auth-field {
    position: relative;
}

.auth-field > svg {
    position: absolute;
    top: 50%;
    left: 0.95rem;
    height: 1.1rem;
    width: 1.1rem;
    margin-top: -0.55rem;
    color: hsl(var(--muted-foreground));
    pointer-events: none;
}

.auth-field .field {
    padding-left: 2.75rem;
}

/* The six boxes of the code, with the one real field lying over them. */
.otp {
    position: relative;
}

.otp-input {
    position: absolute;
    inset: 0;
    z-index: 2;
    height: 100%;
    width: 100%;
    border: 0;
    background: transparent;
    font-size: 16px;
    opacity: 0;
    cursor: text;
}

.otp-cells {
    display: grid;
    grid-template-columns: repeat(6, minmax(0, 1fr));
    gap: 0.5rem;
}

.otp-cell {
    display: grid;
    place-items: center;
    height: 3.5rem;
    border: 1.5px solid hsl(var(--border));
    border-radius: 0.8rem;
    background: hsl(var(--card));
    font-family: 'DM Mono', ui-monospace, SFMono-Regular, monospace;
    font-size: 1.5rem;
    font-weight: 500;
    color: hsl(var(--foreground));
    transition:
        border-color 0.14s ease,
        box-shadow 0.14s ease;
}

.otp-cell.is-filled {
    border-color: hsl(var(--foreground) / 0.35);
}

.otp-cell.is-active {
    border-color: hsl(var(--primary));
    box-shadow: 0 0 0 3px hsl(var(--primary) / 0.25);
}

.otp-cell.is-active:empty::after {
    content: '';
    height: 1.5rem;
    width: 2px;
    border-radius: 1px;
    background: hsl(var(--primary));
    animation: otp-caret 1s steps(1) infinite;
}

.otp-input[aria-invalid='true'] + .otp-cells .otp-cell {
    border-color: hsl(var(--danger));
}

@keyframes otp-caret {
    50% {
        opacity: 0;
    }
}

@media (max-width: 380px) {
    .otp-cells {
        gap: 0.35rem;
    }

    .otp-cell {
        height: 3rem;
        font-size: 1.25rem;
    }
}

.auth-foot {
    font-size: 0.75rem;
    line-height: 1.5;
    text-align: center;
    color: hsl(var(--muted-foreground));
}

@media (prefers-reduced-motion: reduce) {
    .mini-card.is-lift,
    .otp-cell.is-active:empty::after {
        animation: none;
    }

    .auth-progress-bar::after,
    .otp-cell {
        transition: none;
    }
}

@media (forced-colors: active) {
    .auth-card,
    .otp-cell {
        border: 1px solid CanvasText;
    }

    .otp-cell.is-active {
        outline: 2px solid Highlight;
    }
}

/* --------------------------------------------------------------------------
   29. Checking a web address
   While the address of an app is typed, the box beside it shows what was
   found: a turning circle, the icon of the site, or a warning.
   -------------------------------------------------------------------------- */

.url-preview {
    transition:
        border-color 0.14s ease,
        background-color 0.14s ease,
        color 0.14s ease;
}

.url-preview.is-busy {
    color: hsl(var(--primary));
}

.url-preview.is-ok {
    border-color: hsl(var(--success) / 0.45);
    background: hsl(var(--success) / 0.08);
    color: hsl(var(--success));
}

.url-preview.is-bad {
    border-color: hsl(var(--danger) / 0.45);
    background: hsl(var(--danger) / 0.06);
    color: hsl(var(--danger));
}

.url-state {
    margin-top: 0.45rem;
    font-size: 0.8125rem;
    line-height: 1.4;
    color: hsl(var(--muted-foreground));
}

.url-state svg {
    display: inline-block;
    height: 0.95rem;
    width: 0.95rem;
    margin-right: 0.3rem;
    vertical-align: -0.18em;
}

.url-state.is-ok {
    font-weight: 500;
    color: hsl(var(--success));
}

/* --------------------------------------------------------------------------
   30. Moving between pages and views
   Going from the sign-in page to the board fades and rises softly. Inside
   the board, switching a view or an app moves only the board, while the
   bars around it stay still. Without motion it simply changes.
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: no-preference) {
    @view-transition {
        navigation: auto;
    }
}

::view-transition-old(root) {
    animation: vt-out 0.18s ease-in both;
}

::view-transition-new(root) {
    animation: vt-in 0.34s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}

html.vt-board #board {
    view-transition-name: board;
}

html.vt-board::view-transition-old(root),
html.vt-board::view-transition-new(root) {
    animation: none;
}

::view-transition-old(board) {
    animation: vt-out 0.14s ease-in both;
}

::view-transition-new(board) {
    animation: vt-in 0.28s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}

::view-transition-group(board) {
    animation-duration: 0.28s;
}

@keyframes vt-out {
    to {
        opacity: 0;
        transform: translateY(-4px);
    }
}

@keyframes vt-in {
    from {
        opacity: 0;
        transform: translateY(10px);
    }
}

@media (prefers-reduced-motion: reduce) {
    ::view-transition-group(*),
    ::view-transition-old(*),
    ::view-transition-new(*) {
        animation: none !important;
    }

    .url-preview,
    .color-pick label {
        transition: none;
    }

    .color-pick label:hover {
        transform: none;
    }
}
