* { box-sizing: border-box; }

html, body {
    height: 100%;
    margin: 0;
    padding: 0;
    font-family: var(--font-sans);
    color: var(--quindi-text);
    background: var(--quindi-bg);
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
}

button { font-family: inherit; }
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

.ambient-backdrop {
    position: fixed; inset: 0; z-index: -1; overflow: hidden;
    background:
        radial-gradient(60% 50% at 0% 0%, rgba(0, 214, 143, 0.08), transparent 60%),
        radial-gradient(50% 40% at 100% 100%, rgba(0, 214, 143, 0.05), transparent 70%),
        var(--quindi-bg);
}

/* L'orizzonte: l'editor è full-bleed, niente grid layout. Lo chrome (seam,
   rail, header, panel, palette) vive in `position: fixed` SOPRA il canvas. */
.editor-shell {
    position: fixed;
    inset: 0;
}

.page-shell {
    min-height: 100vh;
}

.main { position: absolute; inset: 0; min-height: 0; }

.excalidraw-host { position: absolute; inset: 0; }
.loading {
    position: absolute; inset: 0;
    display: grid; place-items: center;
    color: var(--quindi-text-soft);
}

/* `.editor-canvas` con margine + bordo arrotondato è specifico dello shared
   view (read-only). L'editor full-bleed lo override-a a inset:0/no-radius
   tramite la regola `.editor-shell .editor-canvas` qui sotto. */
.editor-canvas {
    position: absolute; inset: 0;
    border-radius: var(--radius-xl);
    overflow: hidden;
    box-shadow: var(--glass-shadow);
    background: var(--canvas-bg);
}
.editor-shell .editor-canvas {
    inset: 0;
    border-radius: 0;
    box-shadow: none;
}

.brand {
    display: flex; align-items: center; gap: 10px;
    font-weight: 600;
    letter-spacing: -0.01em;
}
.brand h1,
.brand .brand-name {
    font-family: var(--font-hand);
    font-size: 22px;
    margin: 0;
    font-weight: 400;
    letter-spacing: 0;
    color: var(--quindi-text);
}
.brand-mark {
    width: 30px; height: 30px;
    border-radius: var(--radius-sm);
    background: var(--accent);
    display: grid; place-items: center;
    color: #050505;
    font-family: var(--font-hand);
    font-weight: 400; font-size: 18px;
    line-height: 1;
    text-decoration: none;
    transition: transform 0.12s ease;
}
.brand-mark:hover { transform: scale(1.05); text-decoration: none; }

.search-input {
    width: 100%;
    padding: 8px 12px;
    border: 1px solid var(--quindi-border);
    background: var(--quindi-surface-2);
    color: var(--quindi-text);
    border-radius: var(--radius-sm);
    font-size: 13px;
    outline: none;
}
.search-input:focus { border-color: var(--accent); }


.toast {
    position: fixed; bottom: 24px; left: 50%;
    transform: translateX(-50%);
    padding: 10px 16px;
    border-radius: 999px;
    font-size: 13px;
    z-index: 1000;
    background: var(--quindi-surface);
    border: 1px solid var(--quindi-border);
    color: var(--quindi-text);
    box-shadow: var(--glass-shadow-soft);
    animation: toast-in 0.25s ease;
}
@keyframes toast-in { from { opacity: 0; transform: translate(-50%, 8px); } to { opacity: 1; transform: translate(-50%, 0); } }

/* Dashboard / Trash / settings-style pages */
.dashboard {
    padding: 32px;
    max-width: 1200px;
    margin: 0 auto;
}
.dashboard-header {
    display: flex; align-items: center; justify-content: space-between;
    margin-bottom: 24px;
}
/* Page-level top bar: brand on the far left, actions on the right. Sits above
   the sidebar+content grid so the "Q + Quindi.Notepad" lockup owns the
   top-left of the viewport regardless of how the dashboard body is laid out. */
.page-topbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    margin-bottom: 24px;
}
.dashboard-actions { display: flex; gap: 8px; align-items: center; }

/* Anchor for the Export dropdown: the .tag-picker-menu inside is positioned
   absolute against this wrapper, not against the toolbar. */
.export-menu-anchor { position: relative; display: inline-flex; }
.export-menu-anchor .export-menu-caret { opacity: 0.7; margin-left: 2px; }
.export-menu-anchor .glass-button.is-active { background: var(--quindi-surface-2); }
/* Override the tag-picker-menu's default top-right offset (it sits inside a
   row of buttons, not the page corner) so it drops directly under the button. */
.export-menu { right: 0; top: calc(100% + 6px); min-width: 220px; }
.user-chip {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    margin-left: 16px;
    padding: 6px 12px;
    background: var(--quindi-surface-2);
    border: 1px solid var(--quindi-border);
    border-radius: 999px;
    font-size: 13px;
    line-height: 1;
    max-width: 280px;
}
.user-chip-name {
    font-weight: 600;
    color: var(--quindi-text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.user-chip-sep {
    width: 1px;
    height: 14px;
    background: var(--quindi-border);
    flex: 0 0 auto;
}
.user-chip-form { margin: 0; display: inline-flex; }
.user-chip-signout { padding: 0; font-size: 13px; }
.dashboard-panel { padding: 32px; }
.empty-state {
    display: flex; flex-direction: column; gap: 16px; align-items: center;
    color: var(--quindi-text-soft);
    padding: 40px;
}
.doc-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: 14px;
}

/* ----------------------------------------------------------------------
   Visual gallery — replaces the textual grid on the dashboard. Card
   layout is masonry via CSS columns: rows naturally pack to the height
   each card needs, driven by the cached SVG's intrinsic aspect ratio.
   ---------------------------------------------------------------------- */
.doc-gallery {
    column-count: auto;
    column-width: 280px;
    column-gap: 16px;
}

.gallery-card {
    position: relative;
    break-inside: avoid;
    margin: 0 0 16px;
    background: var(--quindi-surface);
    border: 1px solid var(--quindi-border);
    border-radius: var(--radius-md);
    /* overflow stays visible so absolutely-positioned popovers (MoveToFolderMenu)
       can extend past the card. The thumb and overlay clip their own rounded
       corners independently. */
    transition: transform 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;
}
.gallery-card:hover {
    transform: translateY(-2px);
    border-color: var(--accent);
    box-shadow: 0 12px 24px rgba(0, 0, 0, 0.28);
}
.gallery-card.is-archived { opacity: 0.65; }
/* While the tag picker menu is open the card must stack above siblings.
   Cards have position:relative but no z-index by default, so the next card in
   DOM order paints over any absolute child (the menu) that extends past the
   card box. Elevating only the card with the open menu keeps the painting
   intact without affecting hover/transform stacking on the rest of the grid. */
.gallery-card.is-menu-open { z-index: 10; }

/* Freeze the hover transform while the picker menu is open.
   The :hover translateY(-2px) below applies a non-none transform, which by
   CSS spec turns the card into the containing block for its `position: fixed`
   descendants — including .tag-picker-backdrop (inset:0). The backdrop then
   collapses from "covers the viewport" to "covers the card", letting clicks
   on the rest of the grid bypass the close handler and navigate away mid-pick.
   The visible symptom is a flicker when hover toggles and a much worse one
   when the user switches browser tabs and returns (forced repaint snaps
   :hover/:focus-within state, snapping the backdrop's coordinate system with
   it). Disabling transform on the open card eliminates the containing-block
   flip; border/shadow stay so the card still feels active. */
.gallery-card.is-menu-open,
.gallery-card.is-menu-open:hover { transform: none; }

/* Keep the actions strip visible while the menu is open. Without this rule
   the backdrop intercepts the mouse, the card loses :hover, .gallery-actions
   fades to opacity 0, and the "Assegna tag" button (the one the user just
   clicked) ghosts out under their cursor. */
.gallery-card.is-menu-open .gallery-actions {
    opacity: 1;
    pointer-events: auto;
}

.gallery-card-link {
    display: block;
    color: inherit;
    text-decoration: none;
}
.gallery-card-link:hover { text-decoration: none; }

/* Two states managed by JS in quindi.js → quindi.thumbnails:
   • is-placeholder (default markup): the inline ThumbPlaceholder fills the box
   • has-thumb: an <img src=blob:...> with the cached scene SVG, loaded inert */
.gallery-thumb {
    position: relative;
    width: 100%;
    aspect-ratio: 16 / 10;
    /* Excalidraw's default scene background is white; matching it here keeps the
       cached SVG visually continuous with the editor view. The placeholder paints
       on a slightly darker surface to make "no preview yet" obviously different. */
    background: #ffffff;
    overflow: hidden;
    border-radius: var(--radius-md) var(--radius-md) 0 0;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--quindi-text-soft);
}
.gallery-thumb.is-placeholder { background: var(--quindi-surface); }
.gallery-thumb.is-placeholder .thumb-placeholder {
    width: 60%;
    max-width: 200px;
    opacity: 0.55;
    color: var(--quindi-text-soft);
}
.gallery-thumb.has-thumb img.gallery-thumb-img {
    width: 100%;
    height: 100%;
    display: block;
    object-fit: contain;
    user-select: none;
    -webkit-user-drag: none;
}

.gallery-overlay {
    padding: 12px 14px 14px;
    border-top: 1px solid var(--quindi-border);
    border-radius: 0 0 var(--radius-md) var(--radius-md);
    display: flex;
    flex-direction: column;
    gap: 4px;
    background: var(--quindi-surface);
}
.gallery-title {
    font-weight: 600;
    font-size: 14px;
    line-height: 1.35;
    color: var(--quindi-text);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    word-break: break-word;
    /* Riserva sempre lo spazio per 2 righe di titolo: il line-clamp limita gia'
       il massimo, questo blocca il MINIMO. Senza questa riga i titoli a 1 riga
       sono ~19px piu' corti di quelli a 2, e la differenza si propaga lungo il
       column-flow del .doc-gallery shiftando in basso le card sottostanti di
       una colonna rispetto alle altre — l'effetto "righe non allineate" che si
       vedeva con titoli come "Quindi.Notepad - Architecture" (1 riga) vs
       "Quindi.Intelligence - Feature document agent" (2 righe). */
    min-height: calc(2 * 1.35em);
}
.gallery-meta {
    font-size: 11px;
    color: var(--quindi-text-soft);
    font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
    letter-spacing: 0.01em;
}
.gallery-tags {
    display: flex;
    gap: 4px;
    flex-wrap: wrap;
    margin-top: 4px;
    /* Riserva lo spazio di una row di chip anche quando la card non ha tag.
       Senza questo, le card con tag sono ~22px piu' alte di quelle senza e
       il column-count del .doc-gallery sfalsa le righe sottostanti — stesso
       motivo per cui il titolo riserva 2 righe via min-height piu' su.
       Card con 2+ righe di chip restano libere di crescere (flex-wrap). */
    min-height: 22px;
}

/* Pills overlaid top-left on the thumbnail (status badge). The badges row
   is a pure presentational layer; pointer-events on the strip itself are
   off so it doesn't intercept the underlying link's click. */
.gallery-badges {
    position: absolute;
    top: 10px;
    left: 10px;
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
    pointer-events: none;
    /* Reserve space on the right so badges never overlap the action cluster. */
    max-width: calc(100% - 120px);
    z-index: 1;
}
.gallery-status {
    pointer-events: auto;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 8px;
    border-radius: 999px;
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    background: rgba(20, 20, 20, 0.78);
    color: var(--quindi-text);
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
    border: 1px solid rgba(255, 255, 255, 0.06);
    white-space: nowrap;
}
.gallery-status.is-archived {
    background: rgba(229, 72, 77, 0.18);
    color: var(--quindi-red, #F08080);
    border-color: rgba(229, 72, 77, 0.35);
}
.gallery-status.is-published {
    background: rgba(0, 214, 143, 0.18);
    color: var(--accent, #00D68F);
    border-color: rgba(0, 214, 143, 0.35);
}
/* Sharing badge — used in two flavors:
   - "With me" on docs whose OwnerId differs from the current user;
   - "By me · N" on docs the current user owns and has shared with others.
   The element is a <button> (clickable to open the collaborators popover) so we
   need explicit cursor + reset of the default button background; the popover
   itself anchors to .gallery-status-anchor (a position:relative wrapper). */
.gallery-status-anchor {
    position: relative;
    display: inline-flex;
    pointer-events: auto;
}
.gallery-status.is-shared {
    background: rgba(91, 154, 255, 0.18);
    color: #8FB6FF;
    border-color: rgba(91, 154, 255, 0.35);
    cursor: pointer;
    font: inherit;
    text-transform: uppercase;
}
.gallery-status.is-shared:hover {
    background: rgba(91, 154, 255, 0.28);
    border-color: rgba(91, 154, 255, 0.55);
}
.gallery-status.is-shared:focus-visible {
    outline: 1px solid var(--accent);
    outline-offset: 1px;
}
/* Filled, higher-contrast variant scoped to /shared so the dashboard `/`
   keeps the subtler translucent badge. */
.shared-page .gallery-status.is-shared {
    background: var(--accent);
    color: #0A0A0A;
    border-color: var(--accent);
}
.shared-page .gallery-status.is-shared:hover {
    background: var(--accent-hover);
    border-color: var(--accent-hover);
}

.shared-shell {
    padding: 0 24px 80px;
}
.shared-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    margin-bottom: 14px;
}
.shared-tabs {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 4px;
    border: 1px solid var(--quindi-border);
    border-radius: var(--radius-md);
    background: rgba(255, 255, 255, 0.03);
}
.shared-tab,
.shared-segment {
    border: 0;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--quindi-text-soft);
    font: inherit;
    font-size: 13px;
    font-weight: 600;
    padding: 7px 10px;
    cursor: pointer;
    white-space: nowrap;
}
.shared-tab span {
    display: inline-grid;
    place-items: center;
    min-width: 18px;
    padding: 1px 5px;
    margin-left: 6px;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.08);
    color: var(--quindi-text-soft);
    font-size: 10px;
    font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
}
.shared-tab:hover,
.shared-segment:hover {
    color: var(--quindi-text);
    background: rgba(255, 255, 255, 0.06);
}
.shared-tab.is-active,
.shared-segment.is-active {
    color: #0A0A0A;
    background: var(--accent);
}
.shared-tab.is-active span {
    background: rgba(10, 10, 10, 0.18);
    color: rgba(10, 10, 10, 0.78);
}
.shared-search {
    max-width: 360px;
    padding-left: 34px;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%238B95A5' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><circle cx='11' cy='11' r='8'/><path d='m21 21-4.3-4.3'/></svg>");
    background-repeat: no-repeat;
    background-position: 12px center;
}
.shared-workbench {
    display: grid;
    grid-template-columns: minmax(320px, 0.92fr) minmax(380px, 1.08fr);
    gap: 16px;
    align-items: start;
}
.shared-list,
.shared-detail-panel {
    min-height: 480px;
    border: 1px solid var(--quindi-border);
    border-radius: var(--radius-md);
    background: var(--quindi-surface);
}
.shared-list {
    display: flex;
    flex-direction: column;
    padding: 8px;
    gap: 6px;
}
.shared-row {
    position: relative;
    width: 100%;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 8px;
    padding: 12px;
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    background: transparent;
    color: inherit;
    text-align: left;
    cursor: pointer;
}
.shared-row:hover {
    background: rgba(255, 255, 255, 0.045);
    border-color: rgba(255, 255, 255, 0.08);
}
.shared-row.is-active {
    background: var(--share-accent-soft);
    border-color: rgba(0, 214, 143, 0.38);
}
.shared-row.is-active::before {
    content: "";
    position: absolute;
    left: -1px;
    top: 8px;
    bottom: 8px;
    width: 3px;
    border-radius: 2px;
    background: var(--accent);
}
.shared-row-main {
    display: flex;
    flex-direction: column;
    gap: 3px;
}
.shared-row-title {
    color: var(--quindi-text);
    font-size: 14px;
    font-weight: 650;
    line-height: 1.35;
    overflow-wrap: anywhere;
}
.shared-row-meta,
.shared-person-email,
.shared-person-date,
.shared-link-date,
.shared-detail-meta {
    color: var(--quindi-text-soft);
    font-size: 11px;
    font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
}
.shared-row-badges,
.shared-row-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 5px;
}
.shared-row-badge {
    display: inline-flex;
    align-items: center;
    padding: 2px 8px;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.06);
    color: var(--quindi-text-soft);
    font-size: 11px;
    font-weight: 600;
    text-transform: none;
    letter-spacing: 0;
}
.shared-row-badge.is-with {
    color: var(--accent);
    background: var(--share-accent-soft);
}
.shared-row-badge.is-by {
    color: var(--quindi-amber);
    background: var(--quindi-amber-soft);
}
.shared-list-empty,
.shared-detail-loading,
.shared-detail-empty-row,
.shared-readonly-note {
    color: var(--quindi-text-soft);
    padding: 18px;
    text-align: center;
}
.shared-detail-panel {
    position: sticky;
    top: 18px;
    padding: 18px;
}
.shared-detail-empty {
    min-height: 480px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    color: var(--quindi-text-soft);
    gap: 8px;
}
.shared-detail-empty h2,
.shared-detail-header h2 {
    margin: 0;
    color: var(--quindi-text);
    font-size: 20px;
    line-height: 1.25;
    overflow-wrap: anywhere;
}
.shared-detail-empty p { margin: 0; max-width: 280px; }
.shared-detail-empty-icon {
    width: 44px;
    height: 44px;
    display: grid;
    place-items: center;
    border-radius: var(--radius-md);
    color: var(--accent);
    background: var(--share-accent-soft);
}
.shared-detail-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 14px;
    margin-bottom: 16px;
}
.shared-detail-kicker {
    display: inline-block;
    margin: 0 0 6px 0;
    padding: 2px 8px;
    border-radius: 999px;
    background: var(--share-accent-soft);
    color: var(--accent);
    font-size: 10px;
    font-weight: 800;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}
.shared-open-link,
.shared-icon-button {
    width: 32px;
    height: 32px;
    display: inline-grid;
    place-items: center;
    border-radius: var(--radius-sm);
    border: 1px solid var(--quindi-border);
    color: var(--quindi-text);
    background: rgba(255, 255, 255, 0.04);
    cursor: pointer;
    flex: 0 0 auto;
}
.shared-open-link:hover,
.shared-icon-button:hover {
    border-color: rgba(255, 255, 255, 0.18);
    background: rgba(255, 255, 255, 0.08);
}
.shared-icon-button:disabled {
    opacity: 0.55;
    cursor: default;
}
.shared-detail-summary {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 14px;
    margin-bottom: 14px;
    padding: 10px 12px;
    border: 1px solid var(--quindi-border);
    border-radius: var(--radius-sm);
    background: rgba(255, 255, 255, 0.025);
}
.shared-detail-summary > div {
    display: inline-flex;
    align-items: baseline;
    gap: 6px;
    padding: 0;
    border: 0;
    background: transparent;
}
.shared-detail-summary > div + div {
    padding-left: 14px;
    border-left: 1px solid var(--quindi-border);
}
.shared-summary-value {
    display: inline;
    color: var(--quindi-text);
    font-size: 15px;
    font-weight: 700;
    line-height: 1;
}
.shared-summary-label {
    display: inline;
    color: var(--quindi-text-soft);
    font-size: 11px;
    margin-top: 0;
    text-transform: none;
}
.shared-detail-section {
    border-top: 1px solid var(--quindi-border);
    padding-top: 16px;
    margin-top: 16px;
}
.shared-section-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 12px;
    margin-bottom: 12px;
}
.shared-section-header h3 {
    margin: 0;
    color: var(--quindi-text);
    font-size: 14px;
}
.shared-section-header span {
    color: var(--quindi-text-soft);
    font-size: 12px;
}
.shared-grant-form,
.shared-link-create {
    display: grid;
    gap: 8px;
    margin-bottom: 12px;
}
.shared-role-toggle,
.shared-ttl-toggle {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
}
.shared-person-list,
.shared-link-list {
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.shared-person-row,
.shared-link-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px;
    border: 1px solid var(--quindi-border);
    border-radius: var(--radius-sm);
    background: rgba(255, 255, 255, 0.025);
}
.shared-avatar {
    width: 30px;
    height: 30px;
    border-radius: 50%;
    display: inline-grid;
    place-items: center;
    color: #0A0A0A;
    background: var(--accent);
    font-size: 11px;
    font-weight: 800;
    flex: 0 0 auto;
}
.shared-person-list > .shared-person-row:nth-child(5n+2) .shared-avatar {
    background: var(--quindi-amber);
    color: #0A0A0A;
}
.shared-person-list > .shared-person-row:nth-child(5n+3) .shared-avatar {
    background: #B58CFF;
    color: #fff;
}
.shared-person-list > .shared-person-row:nth-child(5n+4) .shared-avatar {
    background: #FF7A7A;
    color: #fff;
}
.shared-person-list > .shared-person-row:nth-child(5n+5) .shared-avatar {
    background: #4FD1C5;
    color: #0A0A0A;
}
.shared-person-meta,
.shared-link-meta {
    min-width: 0;
    flex: 1;
}
.shared-person-name,
.shared-link-id {
    color: var(--quindi-text);
    font-size: 13px;
    font-weight: 650;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.shared-role {
    color: var(--quindi-text-soft);
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
}
.shared-issued-link {
    position: relative;
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 8px;
    padding: 26px 10px 10px;
    margin-bottom: 12px;
    border: 1px solid rgba(0, 214, 143, 0.24);
    border-radius: var(--radius-sm);
    background: rgba(0, 214, 143, 0.08);
}
.shared-issued-link::before {
    content: "New link ready";
    position: absolute;
    top: 8px;
    left: 12px;
    font-size: 10px;
    font-weight: 800;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--accent);
}

@media (max-width: 920px) {
    .shared-toolbar {
        align-items: stretch;
        flex-direction: column;
    }
    .shared-tabs {
        width: 100%;
        overflow-x: auto;
    }
    .shared-search {
        max-width: none;
    }
    .shared-workbench {
        grid-template-columns: 1fr;
    }
    .shared-detail-panel {
        position: static;
        min-height: 0;
    }
}

/* Collaborator popover — anchored under the sharing badge. Backdrop catches
   outside clicks so the popover dismisses without an extra JS listener. */
.collaborator-popover-backdrop {
    position: fixed;
    inset: 0;
    z-index: 10;
    background: transparent;
}
.collaborator-popover {
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    min-width: 240px;
    max-width: 320px;
    padding: 8px;
    background: rgba(20, 20, 20, 0.96);
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: var(--radius-md);
    box-shadow: 0 12px 28px rgba(0, 0, 0, 0.45);
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
    z-index: 11;
    display: flex;
    flex-direction: column;
    gap: 4px;
    color: var(--quindi-text);
    text-transform: none;
    letter-spacing: normal;
    font-weight: 400;
    font-size: 12px;
}
.collaborator-empty {
    padding: 10px 8px;
    color: var(--quindi-text-soft);
    text-align: center;
}
.collaborator-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 6px 8px;
    border-radius: var(--radius-sm);
}
.collaborator-row:hover {
    background: rgba(255, 255, 255, 0.04);
}
.collaborator-avatar {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    display: grid;
    place-items: center;
    background: rgba(91, 154, 255, 0.22);
    color: #8FB6FF;
    font-size: 11px;
    font-weight: 600;
    flex: 0 0 auto;
}
.collaborator-meta {
    flex: 1 1 auto;
    min-width: 0;
}
.collaborator-name {
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.collaborator-email {
    color: var(--quindi-text-soft);
    font-size: 11px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.collaborator-granted {
    color: var(--quindi-text-soft);
    font-size: 10px;
    margin-top: 1px;
    opacity: 0.85;
}
.collaborator-role {
    flex: 0 0 auto;
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    color: var(--quindi-text-soft);
    padding: 2px 6px;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.06);
}
.collaborator-remove {
    flex: 0 0 auto;
    width: 22px;
    height: 22px;
    display: grid;
    place-items: center;
    border-radius: 50%;
    background: transparent;
    border: 1px solid transparent;
    color: var(--quindi-text-soft);
    cursor: pointer;
    transition: background-color 120ms ease, color 120ms ease, border-color 120ms ease;
}
.collaborator-remove:hover {
    background: rgba(229, 72, 77, 0.18);
    color: var(--quindi-red, #F08080);
    border-color: rgba(229, 72, 77, 0.35);
}
.collaborator-remove:disabled {
    opacity: 0.4;
    cursor: progress;
}

/* Top-right action cluster — hidden until hover/focus to keep the card
   visually clean until the user interacts. */
.gallery-actions {
    position: absolute;
    top: 8px;
    right: 8px;
    display: flex;
    gap: 4px;
    z-index: 2;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.12s ease;
}
.gallery-card:hover .gallery-actions,
.gallery-card:focus-within .gallery-actions {
    opacity: 1;
    pointer-events: auto;
}
.gallery-action {
    width: 28px; height: 28px;
    display: grid; place-items: center;
    border: 1px solid rgba(255, 255, 255, 0.06);
    background: rgba(20, 20, 20, 0.8);
    color: var(--quindi-text-soft);
    border-radius: var(--radius-sm);
    cursor: pointer;
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
    transition: background 0.12s ease, color 0.12s ease, border-color 0.12s ease;
}
/* Hover backgrounds stay opaque so the chip reads against bright thumbnails:
   replacing the base rgba(20,20,20,0.8) with a translucent overlay turned
   the icons see-through over light scene previews. The translucent rgba is
   layered on top of a darker base instead of replacing it. */
.gallery-action:hover {
    background: rgba(40, 40, 40, 0.92);
    color: var(--quindi-text);
    border-color: rgba(255, 255, 255, 0.18);
}
.gallery-action.is-destructive:hover {
    background: rgba(60, 24, 26, 0.92);
    color: var(--quindi-red, #F08080);
    border-color: rgba(229, 72, 77, 0.55);
}
.gallery-action:focus-visible { outline: 1px solid var(--accent); outline-offset: 1px; }

/* Compact-card variant — driven by the dashboard's "Anteprime" toggle. The thumb
   wrapper isn't rendered at all in this mode; the card collapses to its title +
   meta + tags + actions strip. Visually closer to the legacy text-only grid but
   reusing the same component / layout / interactions. */
.gallery-card.is-compact .gallery-overlay {
    border-top: none;
    padding: 14px 16px 14px;
    border-radius: var(--radius-md);
}
.gallery-card.is-compact .gallery-actions {
    /* No thumbnail to overlay against — actions are on the card surface itself
       so they need to read against --quindi-surface, not against arbitrary
       scene colors. The hover-only reveal stays. */
    background: transparent;
}
.gallery-card.is-compact .gallery-action {
    background: var(--quindi-surface);
    border-color: var(--quindi-border);
}
.gallery-card.is-compact .gallery-badges {
    /* Without a thumb the absolute-positioned badges would overlap the title.
       Move them into the overlay flow as inline pills. */
    position: static;
    padding: 0 16px;
    margin-top: -6px;
    margin-bottom: 6px;
    max-width: 100%;
}
.gallery-card.is-compact .gallery-status {
    background: rgba(255, 255, 255, 0.04);
    backdrop-filter: none;
}

/* Header toggle — eye / eye-off icon + label, persisted to localStorage. Sits
   inline with the other dashboard-actions buttons but lighter than a full
   GlassButton because it's a preference, not a primary action. */
.thumb-toggle {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 10px;
    border-radius: var(--radius-sm);
    border: 1px solid var(--quindi-border);
    background: transparent;
    color: var(--quindi-text-soft);
    font: inherit;
    font-size: 12px;
    cursor: pointer;
    transition: color 0.12s ease, border-color 0.12s ease, background 0.12s ease;
}
.thumb-toggle:hover {
    color: var(--quindi-text);
    border-color: rgba(255, 255, 255, 0.18);
}
.thumb-toggle.is-on {
    color: var(--accent);
    border-color: rgba(0, 214, 143, 0.35);
    background: rgba(0, 214, 143, 0.08);
}
.thumb-toggle:focus-visible { outline: 1px solid var(--accent); outline-offset: 1px; }
.thumb-toggle svg { display: block; }

/* Drop overlay — full-viewport target rendered on top of everything when the
   user drags files onto the page. The toggle is `body.has-drag-over` set by
   quindi.dashboard's drag handlers; default opacity:0 + pointer-events:none
   keep the element invisible and click-through when no drag is in flight. */
.drop-overlay {
    position: fixed;
    inset: 0;
    z-index: 9999;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(10, 10, 10, 0.55);
    backdrop-filter: blur(4px);
    border: 3px dashed var(--accent, #00D68F);
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.15s ease;
}
body.has-drag-over .drop-overlay {
    opacity: 1;
}
.drop-overlay-message {
    font-size: 22px;
    color: var(--quindi-text, #F4F6F9);
    text-align: center;
    line-height: 1.4;
    font-weight: 600;
}
.drop-overlay-message span {
    display: block;
    margin-top: 6px;
    font-size: 13px;
    font-weight: 400;
    color: var(--quindi-text-soft, #8B95A5);
    font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
}

/* Build stamp — discreet bottom-right marker so users can quote a version when
   reporting issues. Format YYYYMMDD-sha is baked into the assembly by the
   ResolveBuildMetadata MSBuild target in Quindi.Notepad.Web.Blazor.csproj. */
.build-stamp {
    position: fixed;
    bottom: 8px;
    right: 12px;
    font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
    font-size: 11px;
    color: var(--quindi-text-soft, #8B95A5);
    opacity: 0.55;
    pointer-events: none;
    user-select: text;
    z-index: 1;
    letter-spacing: 0.02em;
}

/* Upstream attribution: small footer centrato in basso che da' credito al
   progetto Excalidraw open-source su cui Quindi.Notepad e' costruito.
   pointer-events:auto solo sul link cosi' il resto del footer non intercetta
   eventi sul canvas / sulla dashboard. */
.powered-by {
    position: fixed;
    bottom: 8px;
    left: 50%;
    transform: translateX(-50%);
    font-size: 11px;
    color: var(--quindi-text-soft, #8B95A5);
    opacity: 0.55;
    pointer-events: none;
    z-index: 1;
    letter-spacing: 0.02em;
    white-space: nowrap;
}
.powered-by a {
    color: inherit;
    text-decoration: underline;
    text-underline-offset: 2px;
    pointer-events: auto;
}
.powered-by a:hover { color: var(--accent); }
.doc-card-row { position: relative; }
.doc-card-row:hover .row-action { opacity: 1; pointer-events: auto; }
.doc-card {
    padding: 18px;
    height: 104px;
    color: inherit;
    text-decoration: none;
    transition: transform 0.15s ease, border-color 0.15s ease;
    display: flex; flex-direction: column; justify-content: space-between; gap: 6px;
    background: var(--quindi-surface);
    border: 1px solid var(--quindi-border);
    border-radius: var(--radius-md);
}
.doc-card:hover { transform: translateY(-2px); text-decoration: none; border-color: var(--accent); }
.doc-card-title {
    font-weight: 600; font-size: 15px;
    padding-right: 32px;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    word-break: break-word;
}
.doc-card-meta { font-size: 12px; color: var(--quindi-text-soft); }

/* Action buttons used inside dashboard cards / rail panel doc rows. */
.row-action {
    position: absolute;
    right: 8px; top: 50%;
    transform: translateY(-50%);
    width: 24px; height: 24px;
    display: grid; place-items: center;
    border: none;
    background: transparent;
    color: var(--quindi-text-soft);
    border-radius: var(--radius-sm);
    cursor: pointer;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.12s ease, background 0.12s ease, color 0.12s ease;
}
.row-action:hover { background: rgba(255,255,255,0.08); color: var(--quindi-text); }
.row-action.is-destructive:hover { background: rgba(229, 72, 77, 0.15); color: var(--quindi-red); }
.row-action.is-rename:hover { background: rgba(0, 214, 143, 0.15); color: var(--accent); }
.row-action:focus-visible { opacity: 1; pointer-events: auto; outline: 1px solid var(--accent); outline-offset: 1px; }
.card-action { right: 12px; top: 12px; transform: none; width: 28px; height: 28px; }
/* When a card has both rename + delete, lay them side by side instead of stacked. */
.card-action-rename { right: 48px; }

/* Make Excalidraw canvas inherit the rounded corners (only in shared view). */
.shared-canvas-host .excalidraw-host,
.shared-canvas-host .excalidraw-host .excalidraw,
.shared-canvas-host .excalidraw-host .excalidraw-container,
.shared-canvas-host .excalidraw-host .App { border-radius: inherit; }
.shared-canvas-host .excalidraw-host .excalidraw .layer-ui__wrapper { border-radius: inherit; }

/* Generic small text-button used in rail panel footer + bulk bar. */
.link-btn {
    background: none; border: none;
    padding: 4px 0;
    font: inherit; font-size: 12px;
    color: var(--quindi-text-soft);
    cursor: pointer;
    text-decoration: none;
}
.link-btn:hover { color: var(--accent); text-decoration: none; }
.link-btn.danger { color: var(--quindi-red); }
.link-btn.danger:hover { color: #ff6b70; }
/* Warn variant — amber link, leggermente piu' brillante su hover. Usato per
   azioni che non sono distruttive ma vogliono ancora un richiamo visivo
   distinto dal verde brand (es. Sign out, che porta fuori sessione ma non
   distrugge nulla). */
.link-btn.warn { color: var(--quindi-amber); }
.link-btn.warn:hover { color: #FFC447; }
.link-btn[disabled] { opacity: 0.4; cursor: not-allowed; }

.row-check {
    position: absolute; left: 8px; top: 50%; transform: translateY(-50%);
    width: 14px; height: 14px;
    accent-color: var(--accent);
    cursor: pointer;
}
.panel-doc-row.bulk .panel-doc { padding-left: 32px; }
.panel-doc-row.bulk.selected { background: var(--accent-soft); border-radius: var(--radius-sm); }

/* Trash */
.trash-card { gap: 4px; }
.trash-card .trash-actions { display: flex; gap: 6px; margin-top: 12px; }

/* Share modal */
.share-options { margin: 12px 0; }
.share-label { display: block; font-size: 12px; color: var(--quindi-text-soft); margin-bottom: 8px; }
.share-ttl { display: flex; gap: 6px; flex-wrap: wrap; }
.ttl-pill {
    padding: 6px 12px;
    border: 1px solid var(--quindi-border);
    background: var(--quindi-surface-2);
    color: var(--quindi-text);
    border-radius: var(--radius-sm);
    cursor: pointer;
    font: inherit; font-size: 12px;
    transition: border-color 0.12s ease, background 0.12s ease, color 0.12s ease;
}
.ttl-pill:hover { border-color: var(--accent); }
.ttl-pill.active { background: var(--accent); color: #050505; border-color: var(--accent); }
.share-link {
    display: flex; gap: 8px; align-items: center;
    margin-top: 16px;
}
.share-link .search-input { flex: 1; cursor: pointer; }
.share-meta { color: var(--quindi-text-soft); font-size: 12px; margin: 8px 0 0; }

.share-tabs {
    display: flex; gap: 6px;
    margin: 0 0 16px;
    border-bottom: 1px solid var(--quindi-border);
}
.share-tab {
    padding: 8px 14px;
    background: transparent;
    border: 0;
    border-bottom: 2px solid transparent;
    color: var(--quindi-text-soft);
    cursor: pointer;
    font: inherit; font-size: 13px;
    transition: color 0.12s ease, border-color 0.12s ease;
}
.share-tab:hover { color: var(--quindi-text); }
.share-tab.active { color: var(--quindi-text); border-bottom-color: var(--accent); }

.share-grant-form {
    display: grid;
    grid-template-columns: 1fr auto auto;
    gap: 8px; align-items: center;
    margin-bottom: 16px;
}
.share-grant-form .search-input { width: 100%; }

.share-active { margin-top: 16px; }
.share-active-header {
    display: flex; align-items: center; justify-content: space-between;
    margin-bottom: 8px;
}
.share-active-status { color: var(--quindi-text-soft); font-size: 12px; }
.share-active-list {
    list-style: none; padding: 0; margin: 0;
    display: flex; flex-direction: column; gap: 6px;
}
.share-active-item {
    display: flex; align-items: center; justify-content: space-between;
    gap: 12px;
    padding: 8px 12px;
    background: var(--quindi-surface-2);
    border: 1px solid var(--quindi-border);
    border-radius: var(--radius-sm);
}
.share-active-meta {
    display: flex; flex-direction: column;
    min-width: 0;
}
.share-active-id { font-size: 13px; color: var(--quindi-text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.share-active-expires { font-size: 11px; color: var(--quindi-text-soft); }

/* Shared (read-only) view */
.shared-shell {
    min-height: 100vh;
    display: grid;
    grid-template-rows: 56px 1fr;
}
.shared-topbar {
    display: flex; align-items: center; justify-content: space-between;
    padding: 0 18px;
    border-bottom: 1px solid var(--quindi-border);
    background: var(--quindi-surface);
}
.shared-topbar .brand { color: inherit; text-decoration: none; }
.shared-badge {
    padding: 4px 10px;
    background: var(--quindi-surface-2);
    border: 1px solid var(--quindi-border);
    border-radius: var(--radius-sm);
    font-size: 12px;
    color: var(--quindi-text-soft);
}
.shared-canvas-host {
    position: relative;
    min-height: 0;
}
.shared-canvas-host .editor-canvas {
    position: absolute; inset: 14px;
}

/* Standalone pages (login, settings, notfound) */
.standalone-page {
    min-height: 100vh;
    display: grid; place-items: center;
    padding: 32px;
}
.standalone-card {
    width: 100%; max-width: 480px;
    background: var(--quindi-surface);
    border: 1px solid var(--quindi-border);
    border-radius: var(--radius-lg);
    padding: 32px;
    box-shadow: var(--glass-shadow);
}
.standalone-card h1 {
    margin: 0 0 8px;
    font-family: var(--font-hand);
    font-size: 28px;
    font-weight: 400;
    letter-spacing: 0;
}

/* FocusOnNavigate (Routes.razor) programmatically focuses the page's <h1>
   on every navigation so screen readers announce the new section. Without
   this rule Chrome paints its blue keyboard-focus rectangle around the
   title on every page (visible on /admin, /login, the dashboard, etc.).
   :not(:focus-visible) is *not* enough: Chrome treats focus that lands on
   a fresh document as focus-visible (the navigation might have been
   keyboard-triggered), so the exemption never matches after a navigation.
   Drop the ring unconditionally on h1 — h1 has no tabindex so it isn't in
   the keyboard focus order, and the screen-reader announcement that the
   focus enables is independent of the visual outline. */
h1:focus { outline: none; }
.standalone-card p {
    margin: 0 0 20px; color: var(--quindi-text-soft); font-size: 14px;
}

/* Bug report modal — single-field form, posted to /bug-reports via fetch.
   The textarea owns most of the vertical space; the footer pins the
   character counter on the left and the action buttons on the right. */
.bug-report-help {
    margin: 0 0 12px;
    font-size: 13px;
    color: var(--quindi-text-soft);
    line-height: 1.45;
}
.bug-report-textarea {
    width: 100%;
    box-sizing: border-box;
    padding: 10px 12px;
    background: var(--quindi-surface-2);
    border: 1px solid var(--quindi-border);
    border-radius: var(--radius-sm);
    color: var(--quindi-text);
    font-family: inherit;
    font-size: 13px;
    line-height: 1.5;
    resize: vertical;
    min-height: 140px;
    outline: none;
}
.bug-report-textarea:focus {
    border-color: var(--accent);
}
.bug-report-textarea:disabled {
    opacity: 0.6;
    cursor: not-allowed;
}
.bug-report-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    margin-top: 14px;
}
.bug-report-count {
    font-size: 11px;
    color: var(--quindi-text-soft);
    font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
}
