/* Quantana deploy override — served by nginx, injected via sub_filter. */

/* Hide the Solidtime SVG wordmark and overlay "Quantana" text. */
a:has(> svg[viewBox="0 0 168 30"]) > svg { display: none !important; }
a:has(> svg[viewBox="0 0 168 30"])::after {
    content: "Quantana";
    font-size: 1.875rem;
    font-weight: 700;
    letter-spacing: -0.02em;
    color: currentColor;
    display: inline-block;
    line-height: 1;
}

/* SSO buttons injected on /login and /register (Google, then Microsoft).
   Two of them stack now, so the bottom margin is the gap BETWEEN buttons;
   the divider below carries its own margin for the gap before the form. */
.quantana-sso-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.6rem;
    width: 100%;
    padding: 0.65rem 1rem;
    border: 1px solid #d0d0d0;
    border-radius: 0.375rem;
    background: #fff;
    color: #1f1f1f;
    font-weight: 500;
    text-decoration: none;
    margin-bottom: 0.6rem;
    transition: background 0.15s;
}
.quantana-sso-btn:hover { background: #f5f5f5; }
.quantana-sso-divider {
    display: flex;
    align-items: center;
    text-align: center;
    color: #888;
    font-size: 0.85rem;
    margin: 1rem 0;
}
.quantana-sso-divider::before,
.quantana-sso-divider::after {
    content: "";
    flex: 1;
    border-bottom: 1px solid #d0d0d0;
}
.quantana-sso-divider::before { margin-right: 0.6rem; }
.quantana-sso-divider::after  { margin-left: 0.6rem; }

/* Replaces Register.vue's buggy `hover:text-white` on the "Terms of
   Service" / "Privacy Policy" / "Already registered?" links — that class
   makes the text disappear against the light card background on hover
   (see quantana-sso.js's fixAuthLinkHoverContrast). Matches the readable
   hover color Login.vue's own links use elsewhere on the same page. */
.quantana-hover-fix:hover {
    color: var(--color-text-primary, #18181b) !important;
}

/* Terms / Privacy / Return & Refund Policy footer injected below the
   login and register forms (see quantana-sso.js). */
.quantana-footer-links {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    margin-top: 1.5rem;
    font-size: 0.8rem;
    color: #888;
}
.quantana-footer-links a {
    color: #888;
    text-decoration: underline;
    text-underline-offset: 2px;
}
.quantana-footer-links a:hover { color: #1f1f1f; }
.dark .quantana-footer-links a:hover { color: #fff; }
.quantana-footer-links span { opacity: 0.6; }

/* Google Calendar — Clockify-style overlay on Solidtime's time grid.
   Each Google Calendar event is rendered as a "ghost" block on top of
   the existing calendar columns. Click a ghost to open a popover that
   logs it to the timesheet. A small status pill anchors the connect /
   refresh / disconnect controls. */

/* Regular time entries never show a drag/resize handle on hover. That was
   Solidtime's own resize-by-dragging-the-edge affordance (a thin bar that
   fades in over the top/bottom ~12px of an entry), which on a short entry
   sat on top of — and hid — the title text it was hovering to reveal.
   Removing it does not remove the ability to change an entry's time: the
   edit dialog (opened by clicking the entry) still has explicit start/end
   fields. Unconditional — this is a regular-time-entry fix, unrelated to
   whether any calendar is connected. */
.fc-event-resizer {
    display: none !important;
}

/* Calendar-events lane: a fixed strip on the RIGHT of every day column,
   separated from the regular time-entry area by a vertical rule, so a
   synced Google/Outlook event can never visually overlap a real time entry
   (they used to share the exact same space). Only reserved once at least
   one provider is connected — toggled on <html> by quantana-calendar.js —
   so someone with nothing connected keeps the full-width time-entry area
   they had before this existed. */
:root {
    --qcal-lane-width: 78px;
}
/* The events wrapper only carries a stable, always-present class
   (.fc-events-inset / -expanded) when an org has desktop activity tracking
   enabled — most don't, and in that common case it's an unnamed div with
   only base Tailwind utilities (left-0.5/right-0.5). Its DOM position is
   stable in every case though: CalendarDayColumn.vue always renders it as
   the first child of .fc-timegrid-col, before the now-indicator/tooltips/
   selection overlays, so that structural selector covers all three
   variants (no activity status, week view with it, expanded day view with
   it) with one rule instead of tracking each class separately. */
.qcal-has-events .fc-timegrid-col > div:first-child {
    right: calc(var(--qcal-lane-width) + 6px) !important;
}
/* The separator itself: one rule per day column, full height, sitting right
   at the lane boundary. A pseudo-element on the column Solidtime already
   renders `position: relative` (.fc-timegrid-col) rather than a JS-injected
   div, so it can never itself be mistaken for an event and needs no
   z-index fight with real entries or ghosts. */
.qcal-has-events .fc-timegrid-col::before {
    content: '';
    position: absolute;
    top: 0;
    bottom: 0;
    right: var(--qcal-lane-width);
    width: 1px;
    background: var(--color-border, #d4d4d8);
    z-index: 4;
    pointer-events: none;
}

/* Ghost event on the grid.
   Calendar events drawn over Solidtime's time grid, in pale fills so they
   never out-shout the user's actual timesheet entries. Three states, each
   straight off a flag the /events endpoint returns - no second source of
   truth:
     not logged yet (is_saved false) -> pale blue,  dashed: "ready to log"
     saved          (is_saved true)  -> pale green, solid:  "in the timesheet"
     upcoming       (is_upcoming)    -> pale amber, dashed: "hasn't happened yet"
   Saved wins over upcoming (the overlay only ever applies one state class).
   All keep dark text so they stay legible without a text-shadow.

   Colours are custom properties per state so the light and dark palettes
   below can each be swapped as a block without specificity fights. */
.qcal-ghost {
    /* Light theme (default): the agreed colour key. */
    --qcal-bg: rgba(201, 218, 248, 0.92);          /* #c9daf8 */
    --qcal-bg-hover: rgb(201, 218, 248);
    --qcal-border: rgba(109, 158, 235, 0.75);      /* #6d9eeb */
    --qcal-border-hover: rgb(60, 120, 216);        /* #3c78d8 */
    --qcal-text: #1c4587;
    --qcal-shadow: rgba(28, 69, 135, 0.2);
    --qcal-hatch: rgba(15, 23, 42, 0.07);

    /* Lives in the reserved lane on the right of the column (see above),
       never spanning into the time-entry area on the left — this is what
       keeps a ghost from ever overlapping a real entry. */
    position: absolute;
    left: auto;
    right: 4px;
    width: calc(var(--qcal-lane-width) - 8px);
    z-index: 5;
    background-color: var(--qcal-bg);
    /* Diagonal hatch, independent of hue: real projects here mostly default
       to the same blue as the "not logged" state below, so colour alone
       can't be trusted to separate a ghost from a real, already-logged
       block. The stripe (plus the calendar glyph on the time line) reads as
       "draft overlay" no matter what colour a project happens to use. */
    background-image: repeating-linear-gradient(135deg, var(--qcal-hatch) 0 6px, transparent 6px 12px);
    border: 1.5px dashed var(--qcal-border);
    border-radius: 5px;
    padding: 2px 4px;
    overflow: hidden;
    cursor: pointer;
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
    color: var(--qcal-text);
    box-shadow: none;
    transition: background-color 0.12s, border-color 0.12s, box-shadow 0.12s;
    box-sizing: border-box;
}
.qcal-ghost:hover {
    background-color: var(--qcal-bg-hover);
    border-color: var(--qcal-border-hover);
    box-shadow: 0 2px 8px var(--qcal-shadow);
}
.qcal-ghost-saved {
    --qcal-bg: rgba(217, 234, 211, 0.92);          /* #d9ead3 */
    --qcal-bg-hover: rgb(217, 234, 211);
    --qcal-border: rgba(106, 168, 79, 0.75);       /* #6aa84f */
    --qcal-border-hover: rgb(56, 118, 29);         /* #38761d */
    --qcal-text: #274e13;
    --qcal-shadow: rgba(39, 78, 19, 0.2);
    border-style: solid;
}
.qcal-ghost-upcoming {
    --qcal-bg: rgba(255, 229, 153, 0.92);          /* #ffe599 */
    --qcal-bg-hover: rgb(255, 229, 153);
    --qcal-border: rgba(191, 144, 0, 0.6);         /* #bf9000 */
    --qcal-border-hover: rgb(191, 144, 0);
    --qcal-text: #5c4110;
    --qcal-shadow: rgba(92, 65, 16, 0.2);
}
/* Fourth state: dismissed for this one occurrence only (see
   GoogleCalendarController::ignore()). Flat grey, solid border (not
   dashed — dashed reads as "actionable" on the other three states, and an
   ignored occurrence deliberately is not), reduced opacity, and a
   strikethrough on the title so it reads as "dismissed" even in a
   screenshot with no hover state. No hatch: the hatch means "draft
   overlay, something to do here", which is exactly what this isn't. */
.qcal-ghost-ignored {
    --qcal-bg: rgba(228, 228, 231, 0.75);          /* #e4e4e7 */
    --qcal-bg-hover: rgb(228, 228, 231);
    --qcal-border: rgba(113, 113, 122, 0.5);       /* #71717a */
    --qcal-border-hover: rgb(113, 113, 122);
    --qcal-text: #52525b;
    --qcal-shadow: rgba(0, 0, 0, 0.12);
    background-image: none;
    border-style: solid;
    opacity: 0.75;
    cursor: default;
}
.qcal-ghost-ignored .qcal-ghost-title {
    text-decoration: line-through;
    text-decoration-color: var(--qcal-border);
}
.qcal-ghost-ignored:hover {
    opacity: 1;
}

/* Dark theme (`html.dark`, set by the app's theme setting - not the OS
   preference). The grid is near-black, so the light pastels would glare and
   wash out. Roles invert instead: a deep tint of the same hue as the fill,
   and the light-theme key colour itself as the text, so blue/green/amber
   still read as the same three states.

   Fills are opaque on purpose. A translucent ghost over a real time entry
   let both sets of text show through each other; opaque, the ghost cleanly
   covers what's under it (the light fills are near-opaque for the same
   reason). The dashed borders keep ghosts distinct from real entries, which
   are solid-filled in their project colour. */
.dark .qcal-ghost {
    --qcal-bg: #182233;
    --qcal-bg-hover: #1f2d45;
    --qcal-border: rgba(138, 180, 248, 0.55);      /* #8ab4f8 */
    --qcal-border-hover: rgb(138, 180, 248);
    --qcal-text: #c9daf8;
    --qcal-shadow: rgba(0, 0, 0, 0.5);
    --qcal-hatch: rgba(255, 255, 255, 0.06);
}
.dark .qcal-ghost-saved {
    --qcal-bg: #172a1d;
    --qcal-bg-hover: #1d3625;
    --qcal-border: rgba(129, 201, 149, 0.55);      /* #81c995 */
    --qcal-border-hover: rgb(129, 201, 149);
    --qcal-text: #d9ead3;
}
.dark .qcal-ghost-upcoming {
    --qcal-bg: #2d2610;
    --qcal-bg-hover: #3a3114;
    --qcal-border: rgba(253, 214, 99, 0.55);       /* #fdd663 */
    --qcal-border-hover: rgb(253, 214, 99);
    --qcal-text: #ffe599;
}
.dark .qcal-ghost-ignored {
    --qcal-bg: #27272a;
    --qcal-bg-hover: #303035;
    --qcal-border: rgba(161, 161, 170, 0.45);      /* #a1a1aa */
    --qcal-border-hover: rgb(161, 161, 170);
    --qcal-text: #a1a1aa;
}
/* The dark-brown badge disappears on a dark amber fill; flip it. */
.dark .qcal-ghost-badge {
    background: #fdd663;
    color: #3a2c00;
}

.qcal-ghost-time {
    display: flex;
    align-items: center;
    gap: 3px;
    font-size: 10px;
    line-height: 1.2;
    opacity: 0.92;
    font-weight: 600;
    letter-spacing: 0.02em;
}
.qcal-ghost-icon {
    display: inline-flex;
    width: 9px;
    height: 9px;
    flex-shrink: 0;
    opacity: 0.85;
}
.qcal-ghost-icon svg { width: 100%; height: 100%; }
/* The time range is the one part of this row that can genuinely overflow
   the ~70px lane (a 12-hour locale time can run to "10:30 AM–11:00 AM"),
   so it alone gets ellipsis rather than pushing the badge off the edge. */
.qcal-ghost-time-text {
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    min-width: 0;
}
/* Provider badge: the second colour-independent tell for Google vs Outlook
   (task 5), alongside the calendar icon both already carry. A single
   letter in a small filled circle — brand colours, not brand marks, so it
   stays legible at 9px without needing a full logo. */
.qcal-ghost-provider {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    font-size: 7px;
    font-weight: 700;
    line-height: 1;
    color: #fff;
}
.qcal-ghost-provider-google { background: #4285f4; }
.qcal-ghost-provider-microsoft { background: #0078d4; }
.qcal-ghost-title {
    font-size: 11.5px;
    line-height: 1.25;
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
}
.qcal-ghost-badge {
    position: absolute;
    top: 2px;
    right: 4px;
    font-size: 8px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    padding: 1px 4px;
    border-radius: 3px;
    background: rgba(66, 32, 6, 0.9);
    color: #fef3c7;
    text-shadow: none;
    font-weight: 700;
}
.qcal-ghost-badge-ignored {
    background: rgba(82, 82, 91, 0.9);
    color: #f4f4f5;
}
.dark .qcal-ghost-badge-ignored {
    background: #a1a1aa;
    color: #18181b;
}

/* Hover affordance: "Copy as time entry" + "Ignore", revealed on ghost
   hover. Icon-only (title= carries the label) — the lane is only ~70px of
   usable content width, no room for both buttons to spell themselves out. */
.qcal-ghost-actions {
    position: absolute;
    bottom: 2px;
    right: 3px;
    z-index: 6;
    display: flex;
    gap: 3px;
    opacity: 0;
    transform: translateY(2px);
    transition: opacity 0.12s, transform 0.12s;
    pointer-events: none;
}
.qcal-ghost:hover .qcal-ghost-actions {
    opacity: 1;
    transform: translateY(0);
    pointer-events: auto;
}
.qcal-ghost-action {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    padding: 0;
    border-radius: 4px;
    border: 1px solid rgba(255, 255, 255, 0.25);
    cursor: pointer;
    flex-shrink: 0;
}
.qcal-ghost-action .qcal-icon {
    width: 11px;
    height: 11px;
}
.qcal-ghost-copy { background: rgba(2, 132, 199, 0.92); color: #fff; }
.qcal-ghost-copy:hover { background: rgba(3, 105, 161, 1); }
.qcal-ghost-ignore { background: rgba(113, 113, 122, 0.85); color: #fff; }
.qcal-ghost-ignore:hover { background: rgba(82, 82, 91, 1); }
.qcal-ghost-action:disabled { opacity: 0.5; cursor: default; }

/* Restore: the only action an ignored ghost offers. Full-width (there's
   nothing else competing for the row once Copy/Ignore are gone), same
   hover-reveal pattern as the pair above for a consistent feel. */
.qcal-ghost-restore {
    position: absolute;
    bottom: 2px;
    left: 3px;
    right: 3px;
    z-index: 6;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 3px;
    font: inherit;
    font-size: 9px;
    font-weight: 600;
    line-height: 1;
    padding: 3px 4px;
    border-radius: 4px;
    border: 1px solid rgba(255, 255, 255, 0.3);
    background: rgba(82, 82, 91, 0.9);
    color: #fff;
    cursor: pointer;
    opacity: 0;
    transform: translateY(2px);
    transition: opacity 0.12s, transform 0.12s;
    pointer-events: none;
}
.qcal-ghost-restore .qcal-icon {
    width: 10px;
    height: 10px;
}
.qcal-ghost-ignored:hover .qcal-ghost-restore {
    opacity: 1;
    transform: translateY(0);
    pointer-events: auto;
}
.qcal-ghost-restore:hover { background: rgba(63, 63, 70, 1); }
.qcal-ghost-restore:disabled { opacity: 0.5; cursor: default; }

/* Log modal.
   Matches Solidtime's own "Create manual time entry" dialog (DialogModal +
   TimeEntryCreateModal) and is coloured ONLY through Solidtime's theme
   variables from packages/ui/styles.css. Those are redefined under
   :root.dark / :root.light, so this dialog follows the app's theme setting
   with no dark-mode rules of its own. Each var() carries the light value as
   its fallback in case a variable is ever renamed upstream.

   Rules are scoped under .qcal-modal so they outrank @tailwindcss/forms,
   which styles every bare input/select/checkbox in the app. */
.qcal-modal-backdrop {
    position: fixed;
    inset: 0;
    z-index: 10000;
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding: 0.75rem 0.5rem;
    overflow: auto;
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
}
/* Solidtime's overlay: its own page background at 30%. */
.qcal-modal-backdrop::before {
    content: "";
    position: fixed;
    inset: 0;
    background: var(--theme-color-default-background, #fcfcfc);
    opacity: 0.3;
}
@media (min-width: 768px) { .qcal-modal-backdrop { padding-top: 3.5rem; } }
@media (min-width: 1280px) { .qcal-modal-backdrop { padding-top: 6rem; } }

.qcal-modal {
    position: relative;
    width: 100%;
    max-width: 42rem;
    background: var(--theme-color-default-background, #fcfcfc);
    color: var(--color-text-primary, #18181b);
    border: 1px solid var(--color-border-tertiary, #dfdfdf);
    border-radius: 0.5rem;
    box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
    font-family: inherit;
    font-size: 0.8125rem;
    line-height: 1.125rem;
    /* Native pickers (select lists, date popup, icons) follow the theme too. */
    color-scheme: light;
}
.dark .qcal-modal { color-scheme: dark; }
.qcal-modal *,
.qcal-modal *::before,
.qcal-modal *::after { box-sizing: border-box; }

.qcal-modal-body { padding: 1rem; }
@media (min-width: 1024px) { .qcal-modal-body { padding: 1rem 1.5rem; } }
.qcal-modal-title {
    font-size: 1.125rem;
    line-height: 1.5rem;
    font-weight: 500;
    color: var(--color-text-primary, #18181b);
}
.qcal-modal-content {
    margin-top: 1rem;
    color: var(--color-text-secondary, #3f3f46);
}

/* Inputs, selects and input-style buttons (Solidtime's TextInput /
   Button variant="input" / SelectTrigger). */
.qcal-modal .qcal-input {
    display: block;
    width: 100%;
    height: 2.25rem;
    margin: 0;
    padding: 0.25rem 0.75rem;
    border: 1px solid var(--theme-color-input-border, #d1d1d1);
    border-radius: 6px;
    background-color: var(--theme-color-input-background, transparent);
    background-image: none;
    color: var(--color-text-primary, #18181b);
    font: inherit;
    font-size: 0.8125rem;
    line-height: 1.125rem;
    box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
    outline: none;
    -webkit-appearance: none;
    appearance: none;
}
.qcal-modal .qcal-input::placeholder {
    color: var(--color-text-quaternary, #a1a1aa);
    opacity: 1;
}
.qcal-modal .qcal-input:focus-visible {
    border-color: transparent;
    box-shadow: 0 0 0 2px var(--theme-color-ring, rgba(0, 0, 0, 0.7));
    outline: none;
}
.qcal-modal .qcal-select {
    padding-left: 2rem;
    font-weight: 500;
    cursor: pointer;
    white-space: nowrap;
    text-overflow: ellipsis;
}
.qcal-modal .qcal-btn-input {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    width: auto;
    font-weight: 500;
    white-space: nowrap;
    cursor: pointer;
}

.qcal-icon {
    display: inline-flex;
    width: 1rem;
    height: 1rem;
    flex-shrink: 0;
    color: var(--theme-color-icon-default, #a1a1aa);
}
.qcal-icon svg { width: 100%; height: 100%; }

/* Project / tags / billable row */
.qcal-row {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 0.5rem;
    padding-top: 1rem;
}
.qcal-project {
    position: relative;
    flex: 1 1 14rem;
    min-width: 0;
}
/* The trigger button and its dot/label carry the real Button component's
   own utility classes straight from the JS (see openLogPopover) — nothing
   to style for them here. */
/* .qcal-modal prefix for specificity: this shares .qcal-tags-panel's base
   rules (declared later in the file) and must win the position/width tie. */
.qcal-modal .qcal-project-panel {
    left: 0;
    right: auto;
    width: 20rem;
    max-width: calc(100vw - 4rem);
}
.qcal-project-item {
    /* dot+name on the left, star on the right — .qcal-tags-item alone is
       flex-start, fine for a checkbox row but not for this space-between one. */
    justify-content: space-between;
}
.qcal-project-item-name {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
/* "Favourites" group header, same wording/position as
   TimeTrackerProjectTaskDropdown.vue's client-group row. */
.qcal-menu-group-header {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0.5rem 0.5rem 0.25rem;
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--color-text-tertiary, #57575c);
}
.qcal-row-actions {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-shrink: 0;
}
.qcal-billable { position: relative; }
.qcal-modal .qcal-billable .qcal-select {
    width: auto;
    padding-left: 2.25rem;
}
.qcal-select-lead {
    position: absolute;
    left: 0.75rem;
    top: 50%;
    transform: translateY(-50%);
    pointer-events: none;
}

/* Tags checklist (Solidtime's TagDropdown, minus inline creation) */
.qcal-tags { position: relative; }
.qcal-tags-panel {
    position: absolute;
    right: 0;
    top: calc(100% + 0.25rem);
    z-index: 2;
    width: 15rem;
    padding: 0.25rem;
    background: var(--color-bg-elevated, var(--theme-color-card-background, #ffffff));
    border: 1px solid var(--popover-border, #e5e5e5);
    border-radius: 6px;
    box-shadow: var(--theme-shadow-dropdown, 0 1px 3px 0 rgb(0 0 0 / 0.1));
}
.qcal-tags-panel[hidden] { display: none; }
.qcal-modal .qcal-tags-search {
    height: 2rem;
    margin-bottom: 0.25rem;
}
.qcal-tags-list {
    max-height: 14rem;
    overflow-y: auto;
}
.qcal-tags-item {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.375rem 0.5rem;
    border-radius: 4px;
    color: var(--color-text-primary, #18181b);
    cursor: pointer;
}
.qcal-tags-item:hover { background: var(--color-bg-tertiary, #eeeeef); }
.qcal-modal .qcal-tags-item input {
    width: 0.875rem;
    height: 0.875rem;
    margin: 0;
    border-radius: 4px;
    border-color: var(--theme-color-input-border, #d1d1d1);
    background-color: var(--theme-color-input-background, transparent);
    color: rgb(var(--color-accent-500, 14, 165, 233));
    accent-color: rgb(var(--color-accent-500, 14, 165, 233));
    cursor: pointer;
}
/* The background above outranks the forms plugin's checked fill, which
   would leave its white tick invisible on a light background. */
.qcal-modal .qcal-tags-item input:checked {
    background-color: currentColor;
    border-color: transparent;
}
.qcal-tags-empty {
    padding: 0.5rem;
    color: var(--color-text-tertiary, #57575c);
}

/* Duration + start/end (Solidtime's TimeRangeFields) */
.qcal-time-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1rem;
    padding-top: 1rem;
}
.qcal-field-duration { grid-column: span 2 / span 2; }
@media (min-width: 640px) {
    .qcal-time-grid { grid-template-columns: repeat(5, minmax(0, 1fr)); }
    .qcal-field-duration { grid-column: span 3 / span 3; }
}
.qcal-field {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    min-width: 0;
}
.qcal-label {
    margin-bottom: 0.25rem;
    font-size: 0.8125rem;
    font-weight: 500;
    line-height: 1;
    color: var(--color-text-secondary, #3f3f46);
}
.qcal-modal .qcal-duration { color: var(--color-text-secondary, #3f3f46); }
.qcal-modal .qcal-time {
    text-align: center;
    font-variant-numeric: tabular-nums;
}
.qcal-modal .qcal-date {
    padding: 0.25rem 0.5rem;
    font-weight: 500;
    cursor: pointer;
}
.qcal-modal .qcal-date::-webkit-calendar-picker-indicator {
    cursor: pointer;
    opacity: 0.6;
}
.qcal-hint {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    font-size: 0.75rem;
    line-height: 1rem;
    color: var(--color-text-secondary, #3f3f46);
}
.qcal-hint .qcal-icon { color: var(--color-text-quaternary, #a1a1aa); }
.qcal-hint strong { font-weight: 600; }

.qcal-feedback {
    padding-top: 0.75rem;
    font-size: 0.75rem;
    color: #dc2626;
}
.qcal-feedback:empty { display: none; }
.dark .qcal-feedback { color: #f87171; }

/* Footer + buttons. The buttons themselves carry Solidtime's own
   SecondaryButton.vue / PrimaryButton.vue utility classes straight from the
   JS, not a hand-matched lookalike here — nothing to style for them. */
.qcal-modal-footer {
    display: flex;
    justify-content: flex-end;
    gap: 0.75rem;
    padding: 1rem 1.5rem;
    border-top: 1px solid var(--theme-color-card-background-separator, #dfdfdf);
    background: var(--theme-color-default-background, #fcfcfc);
    border-radius: 0 0 0.5rem 0.5rem;
}

/* The status pill (Connect / Refresh / Disconnect, docked in the calendar
   toolbar) was removed along with its markup — connections are managed only
   in the Calendar settings dialog now. Its rules went with it. */

