html {
    font-size: 14px;
}

.h2, h2 {
    font-size: 1.75rem !important;
}


@media (min-width: 768px) {
    html {
        font-size: 16px;
    }
}

@media (min-width: 600px) {
    .dropdown:hover .dropdown-menu {
        display: block;
        margin-top: 0; /* remove the gap so it doesn't close */
        right:0;
    }
    /* Per-item dropdowns inside todo items (estimate, deadline, three-dot menu)
       should only open on tap/click, not on hover — hover-open there is
       confusing. :not(.show) ensures Bootstrap's click-open behavior still
       wins when the user actually activates the dropdown. */
    #todo-list .dropdown:hover > .dropdown-menu:not(.show) {
        display: none;
    }
}

.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
    box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;
}

html {
    position: relative;
    min-height: 100%;
}

body {
    margin-bottom: 60px;
}

.help-container #help-toggle {
    z-index: 100;
}


.help-container #help-content {
    margin-top: 1rem;
    max-width: 300px;
    background-color: var(--bs-body-bg);
    z-index: 101;
}

#apps-content {
    margin-top: 1rem;
    max-width: 300px;
    background-color: var(--bs-body-bg);
    z-index: 101;
}

.app-icon {
    width: 1.5em;
    fill: white;
}

.todocategory {
    user-select: none;
    -moz-user-select: none;
    -khtml-user-select: none;
    -webkit-user-select: none;
    -o-user-select: none;
}

.handle {
    cursor: move;
}

.spiciness-indicator {
    position: absolute;
    font-size: 0.6rem;
    transform: translateY(-100%);
}
.strikethrough {
text-decoration: line-through;
}

.progress-00 {
    background: var(--bs-body-bg) !important;
}
.progress-10 {
    background: linear-gradient(to right, var(--bs-tertiary-color) 0%, var(--bs-tertiary-color) 10%, var(--bs-body-bg) 10%, var(--bs-body-bg) 100%) !important;
}
.progress-20 {
    background: linear-gradient(to right, var(--bs-tertiary-color) 0%, var(--bs-tertiary-color) 20%, var(--bs-body-bg) 20%, var(--bs-body-bg) 100%) !important;
}
.progress-30 {
    background: linear-gradient(to right, var(--bs-tertiary-color) 0%, var(--bs-tertiary-color) 30%, var(--bs-body-bg) 30%, var(--bs-body-bg) 100%) !important;
}
.progress-40 {
    background: linear-gradient(to right, var(--bs-tertiary-color) 0%, var(--bs-tertiary-color) 40%, var(--bs-body-bg) 40%, var(--bs-body-bg) 100%) !important;
}
.progress-50 {
    background: linear-gradient(to right, var(--bs-tertiary-color) 0%, var(--bs-tertiary-color) 50%, var(--bs-body-bg) 50%, var(--bs-body-bg) 100%) !important;
}
.progress-60 {
    background: linear-gradient(to right, var(--bs-tertiary-color) 0%, var(--bs-tertiary-color) 60%, var(--bs-body-bg) 60%, var(--bs-body-bg) 100%) !important;
}
.progress-70 {
    background: linear-gradient(to right, var(--bs-tertiary-color) 0%, var(--bs-tertiary-color) 70%, var(--bs-body-bg) 70%, var(--bs-body-bg) 100%) !important;
}
.progress-80 {
    background: linear-gradient(to right, var(--bs-tertiary-color) 0%, var(--bs-tertiary-color) 80%, var(--bs-body-bg) 80%, var(--bs-body-bg) 100%) !important;
}
.progress-90 {
    background: linear-gradient(to right, var(--bs-tertiary-color) 0%, var(--bs-tertiary-color) 90%, var(--bs-body-bg) 90%, var(--bs-body-bg) 100%) !important;
}
.progress-100 {
    background: var(--bs-tertiary-color) !important;
}
@media (max-width: 1200px) {
    /* Define the grid for the first unordered list in the collapsed menu */
    .navbar-collapse .navbar-nav:first-of-type {
        display: grid;
        grid-template-columns: repeat(2, 1fr); /* Adjust number of columns as needed */
        gap: 10px; /* Gap between the grid items */
        padding: 10px;
    }

    /* Style each menu item in the first unordered list as a square button */
    .navbar-nav:first-of-type .nav-item {
        display: flex;
        align-items: center;
        justify-content: center;
        border-width: 2px !important;
        width: 100px; /* Adjust width for square size */
        height: 100px; /* Adjust height for square size */
    }

        .navbar-nav:first-of-type .nav-item .nav-link {
            display: flex; /* Use flexbox for centering */
            align-items: center; /* Center vertically */
            justify-content: center; /* Center horizontally */
            width: 100%;
            height: 100%;
            text-align: center;
            padding: 0;
        }

    /* Make the menu float downwards from the navbar */
    .navbar-collapse {
        position: absolute;
        right:10px;
        top: 100%; /* Align with the bottom of the navbar */
        width: 100%; /* Make sure the menu takes the full width of its container */
        max-width: 230px;
        background-color: var(--bs-body-bg); /* Set an appropriate background color */
        z-index: 1000; /* High z-index to ensure it's above other content */
        box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1); /* Optional: Add a shadow for better separation from content */
    }
}


/* Custom styling for the two-line language selector dropdown */
.choices__item--choice .language-native-bold {
    font-weight: bold;
    line-height: 1.2;
}

.choices__item--choice .language-english-italic {
    font-style: italic;
    font-size: 0.9em;
    opacity: 0.8;
    line-height: 1.2;
}

/* Export Modal Styles */
.export-modal-overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.5);
    z-index: 10000;
    align-items: center;
    justify-content: center;
    padding: 1rem;
}

.export-modal {
    position: relative;
    background-color: var(--bs-body-bg);
    color: var(--bs-body-color);
    padding: 1.5rem;
    border-radius: 0.5rem;
    box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3);
    max-width: 480px;
    width: 100%;
    max-height: 90vh;
    overflow-y: auto;
}

.export-modal-close {
    position: absolute;
    top: 0.5rem;
    right: 0.5rem;
    background: transparent;
    border: none;
    font-size: 1.1rem;
    line-height: 1;
    padding: 0.4rem 0.55rem;
    cursor: pointer;
    color: var(--bs-secondary-color);
    border-radius: 0.25rem;
}

.export-modal-close:hover,
.export-modal-close:focus {
    color: var(--bs-body-color);
    background-color: var(--bs-secondary-bg);
}

.export-modal-title {
    margin: 0 2rem 0.75rem 0;
}

.export-modal-body {
    margin-bottom: 1.25rem;
    line-height: 1.5;
}

.export-modal-body code {
    background-color: var(--bs-secondary-bg);
    padding: 0.1rem 0.35rem;
    border-radius: 0.25rem;
    font-size: 0.9em;
}

/* Goblin Tools Pro
   ----------------
   Reuses .export-modal-* for the shell; these are only the deltas. The one
   real colour decision: goblin green existed as scattered literals (#97C906 /
   #CCE969 in meta tags and the About hero) and is now a variable, so Pro can
   be visually distinct from Bootstrap's stock-blue --bs-primary. */
:root {
    --gt-goblin-green: #97C906;
    --gt-goblin-green-light: #CCE969;
}

/* Above the export modal's 10000 — Pro can be opened from on top of it. */
.gt-pro-overlay {
    z-index: 10001;
}

/* Clerk's sign-up component needs more room than the 480px export cap. */
.gt-pro-modal {
    max-width: 520px;
}

/* Wider again while the pitch and the sign-in control sit side by side. */
.gt-pro-modal.gt-pro-modal-wide {
    max-width: 900px;
}

.gt-pro-split {
    display: flex;
    gap: 1.75rem;
    align-items: flex-start;
    /* Clear the close button, which is absolutely positioned over the modal's
       top-right corner. The single-column panes dodge it with a right margin on
       their title, but the right column here is full width, so insetting it
       would leave the social buttons narrower than the input beneath them.
       Dropping both columns keeps them level with each other. Extra headroom
       so the Clerk form's "Last used" badge, which sits above the first button,
       has clear space rather than crowding the top edge. */
    padding-top: 1.75rem;
}

.gt-pro-pitch {
    flex: 1 1 46%;
    min-width: 0;
    /* A little breathing room off the left edge of the modal. */
    padding-left: 0.5rem;
}

.gt-pro-action {
    flex: 1 1 54%;
    min-width: 0;
    display: flex;
    flex-direction: column;
    /* Room to the right of the form so the "Last used" badge on the social
       button isn't pressed against the modal edge. */
    padding-right: 0.5rem;
    /* Top-aligned, not centred: the pitch column is much taller, so centring
       left the sign-in form floating in the middle with a large empty gap above
       it. Starting level with the heading opposite looks deliberate. */
    justify-content: flex-start;
}

.gt-pro-action .gt-pro-clerk {
    min-height: 0;
    align-items: flex-start;
}

/* One column on anything narrower than a tablet: reading the pitch and filling
   in a form side by side stops being possible long before the modal runs out
   of width. */
@media (max-width: 767.98px) {
    .gt-pro-modal.gt-pro-modal-wide {
        max-width: 520px;
    }

    .gt-pro-split {
        flex-direction: column;
        gap: 1rem;
        /* Stretch, not flex-start: once the columns are stacked they must fill
           the modal width. Left as flex-start (which is right for the desktop
           row) each column shrinks to its content and hugs the left, which is
           why the sign-in control sat narrow and off to one side. */
        align-items: stretch;
    }

    /* Put the action first once stacked: someone who already knows they want it
       should not have to scroll past the whole pitch to sign in. */
    .gt-pro-action {
        order: -1;
        align-self: auto;
    }
}

.gt-pro-features {
    list-style: none;
    padding: 0;
    margin: 0 0 1.25rem 0;
}

.gt-pro-features li {
    display: flex;
    gap: 0.75rem;
    align-items: flex-start;
    padding: 0.5rem 0;
}

.gt-pro-features li i {
    color: var(--gt-goblin-green);
    margin-top: 0.25rem;
    width: 1.25rem;
    text-align: center;
    flex-shrink: 0;
}

.gt-pro-features li div {
    display: flex;
    flex-direction: column;
}

.gt-pro-features li strong {
    line-height: 1.3;
}

.gt-pro-features li span {
    color: var(--bs-secondary-color);
    font-size: 0.9em;
    line-height: 1.4;
}

.gt-pro-free-note {
    display: flex;
    gap: 0.6rem;
    align-items: flex-start;
    background-color: rgba(151, 201, 6, 0.12);
    border-left: 3px solid var(--gt-goblin-green);
    border-radius: 0.25rem;
    padding: 0.75rem;
    margin-bottom: 1.25rem;
    line-height: 1.45;
}

.gt-pro-free-note i {
    color: var(--gt-goblin-green);
    margin-top: 0.2rem;
}

/* "Coming soon to the apps." Informational, not promotional: a muted grey box
   so it reads as a heads-up rather than another selling point. Pro is web-only
   for now because the app stores take a cut of in-app purchases. */
.gt-pro-apps-note {
    display: flex;
    gap: 0.6rem;
    align-items: flex-start;
    background-color: var(--bs-secondary-bg);
    border-left: 3px solid var(--bs-border-color);
    border-radius: 0.25rem;
    padding: 0.75rem;
    margin-bottom: 1.25rem;
    line-height: 1.45;
    color: var(--bs-secondary-color);
    font-size: 0.9rem;
}

.gt-pro-apps-note i {
    margin-top: 0.2rem;
}

/* Lapsed-subscription warning bar. Sticks to the top of the viewport on every
   page: access is still full, so this must not block anything, but it does have
   to be impossible to miss for the few days it is up. Amber rather than red,
   because nothing is broken yet. */
.gt-pro-grace {
    position: sticky;
    top: 0;
    z-index: 1035;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: 0.75rem;
    padding: 0.6rem 1rem;
    background-color: #ffc107;
    color: #241c00;
    font-weight: 600;
    line-height: 1.35;
    text-align: center;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
}

.gt-pro-grace i {
    flex-shrink: 0;
}

.gt-pro-grace .btn {
    flex-shrink: 0;
}

/* The price. Deliberately the same shape and weight as the stays-free note it
   sits directly above, so the two read as a matched pair: this is what the
   extras cost, that is what stays free. Understated on purpose. */
.gt-pro-price-box {
    display: flex;
    gap: 0.6rem;
    align-items: flex-start;
    background-color: rgba(151, 201, 6, 0.12);
    border-left: 3px solid var(--gt-goblin-green);
    border-radius: 0.25rem;
    padding: 0.75rem;
    margin-bottom: 0.5rem;
    font-weight: 600;
    line-height: 1.45;
}

.gt-pro-price-box i {
    color: var(--gt-goblin-green);
    margin-top: 0.2rem;
}

/* Clerk injects its own styles; just don't let it overflow the panel. */
/* Reserves the Clerk control's footprint and hosts the loading spinner over it,
   so the panel keeps its size while ClerkJS downloads and mounts. */
.gt-pro-clerk-wrap {
    position: relative;
    min-height: 300px;
}

.gt-pro-clerk-spinner {
    position: absolute;
    inset: 0;
    align-items: center;
    justify-content: center;
    /* display is toggled inline (none <-> flex) by pro-auth.js. */
}

.gt-pro-clerk {
    display: flex;
    justify-content: center;
    min-height: 300px;
}

/* Paddle renders its inline checkout iframe into this element. Reserve a
   sensible footprint so the panel doesn't jump while paddle.js loads, and let
   the iframe take the full width. Paddle drives the height from there. */
.gt-pro-checkout-frame {
    width: 100%;
    min-height: 300px;
}

.gt-pro-checkout-frame iframe {
    width: 100% !important;
    min-width: 100% !important;
}

.gt-pro-clerk > * {
    max-width: 100%;
}

/* ============================================================
   Clerk components, restyled to look like part of the site
   ============================================================

   Clerk is loaded with `cssLayerName: 'clerk'` (see pro-auth.js), so every rule
   it injects lives inside `@layer clerk`. Unlayered author CSS beats layered
   CSS at ANY specificity, which is what lets the plain `.cl-*` selectors below
   win. Without that layer these would lose: Clerk styles its controls with
   selectors like `.cl-internal-xxxx[data-variant="default"]`, which is
   specificity (0,2,0) and beats a single class no matter how the stylesheets
   are ordered.

   Colours are set here rather than through Clerk's `appearance` because
   Bootstrap's custom properties are live: flipping `data-bs-theme` re-resolves
   them with no JavaScript and, crucially, without remounting the component. A
   remount would discard a half-typed email or an in-progress verification code.
   (Clerk's own `appearance.variables` bake a literal at mount time, and this
   build reads no `--clerk-color-*` hooks of its own, so CSS is the only route
   that tracks the theme.)

   Only the documented `.cl-<descriptor>` classes are targeted. The
   `.cl-internal-*` hashes in the DOM are build artefacts that change between
   releases, and we track a floating major version. */

/* --- Structure: strip the third-party card chrome ------------------------- */

.cl-rootBox {
    width: 100%;
    max-width: none;
}

/* cardBox is the outer wrapper carrying the border, the drop shadow and a fixed
   25rem width. card is the inner surface with its own border and padding. Both
   have to go for the control to sit flat on our modal. */
.cl-cardBox {
    width: 100%;
    max-width: none;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    background: transparent;
    /* Clerk ships this with overflow:hidden to clip its card's rounded corners.
       We've stripped the border, radius and shadow, so it clips nothing useful
       any more — but it WAS cropping the "Last used" badge, which Clerk pins
       protruding above the top-right of the social button. Let it show. */
    overflow: visible;
}

.cl-card {
    background: transparent;
    border: 0;
    box-shadow: none;
    padding: 0;
    margin: 0;
    /* Clerk centres its card text; our forms are left-aligned. */
    text-align: left;
    color: var(--bs-body-color);
}

/* Clerk gives the footer a muted fill and a top border, which reads as a
   separate tray bolted under the form. */
.cl-footer,
.cl-footerAction,
.cl-footerPages {
    background: transparent;
    border-top: 0;
    box-shadow: none;
}

/* --- Typography and colour ---------------------------------------------- */

.cl-headerTitle {
    text-align: left;
    font-size: 1.15rem;
    color: var(--bs-body-color);
}

/* "Continue to Goblin Tools" on the first sign-in screen says nothing the
   pitch beside it has not already said, so it goes.
   Scoped to the START step only, and deliberately not to `.cl-headerTitle` in
   general: on later steps the heading is the only thing telling you what is
   happening ("Check your email", "Enter your password", "Create your
   account"), and losing those would leave a form with no context. */
#gt-pro-modal .cl-signIn-start .cl-header,
#gt-pro-modal .cl-signUp-start .cl-header {
    display: none;
}

/* Clerk's own "Don't have an account? Sign up" footer link navigates to its
   HOSTED page (accounts.dev / your Clerk domain), taking the visitor off the
   site entirely and away from the modal. Hidden in favour of the buttons in
   .gt-pro-switch, which swap the pane in place. */
#gt-pro-modal .cl-footerAction {
    display: none;
}

/* Our own switch between signing in and registering. */
.gt-pro-switch {
    margin-top: 0.25rem;
    padding-top: 0.9rem;
    border-top: 1px solid var(--bs-border-color);
    text-align: center;
    font-size: 0.9rem;
    color: var(--bs-secondary-color);
}

/* The "you are signing in as ..." chip on the password step. Clerk centres its
   contents, which left the address sitting off to one side of the pencil
   button rather than reading as a labelled value. */
.cl-identityPreview {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    text-align: left;
}

.cl-identityPreviewText {
    flex: 1 1 auto;
    min-width: 0;
    overflow-wrap: anywhere;
}

.cl-headerSubtitle,
.cl-dividerText,
.cl-footerActionText,
.cl-formFieldHintText,
.cl-formFieldInfoText,
.cl-identityPreviewText {
    text-align: left;
    color: var(--bs-secondary-color);
}

.cl-formFieldLabel,
.cl-formFieldLabelRow,
.cl-otpCodeFieldLabel {
    color: var(--bs-body-color);
}

.cl-formFieldErrorText,
.cl-otpCodeFieldErrorText,
.cl-alertText {
    color: var(--bs-danger-text-emphasis, var(--bs-danger));
}

.cl-footerActionLink,
.cl-formFieldAction,
.cl-formResendCodeLink,
.cl-backLink,
.cl-footerPagesLink,
.cl-identityPreviewEditButton {
    color: var(--bs-link-color);
}

.cl-footerActionLink:hover,
.cl-formFieldAction:hover,
.cl-formResendCodeLink:hover,
.cl-backLink:hover,
.cl-footerPagesLink:hover,
.cl-identityPreviewEditButton:hover {
    color: var(--bs-link-hover-color);
}

.cl-dividerLine {
    background-color: var(--bs-border-color);
}

/* --- Form controls, matched to Bootstrap's ------------------------------- */

/* Clerk outlines inputs and buttons with box-shadow rings rather than borders,
   so a real border is what makes them sit alongside our own form controls. */
.cl-formFieldInput,
.cl-otpCodeFieldInput,
.cl-socialButtonsBlockButton,
.cl-alternativeMethodsBlockButton,
.cl-identityPreview {
    box-shadow: none;
    border: 1px solid var(--bs-border-color);
    background-color: var(--bs-body-bg);
    color: var(--bs-body-color);
}

.cl-formFieldInput:focus,
.cl-formFieldInput:focus-visible,
.cl-otpCodeFieldInput:focus,
.cl-otpCodeFieldInput:focus-visible {
    border-color: var(--gt-goblin-green);
    box-shadow: 0 0 0 0.2rem rgba(151, 201, 6, 0.25);
    background-color: var(--bs-body-bg);
    color: var(--bs-body-color);
}

.cl-socialButtonsBlockButtonText,
.cl-alternativeMethodsBlockButtonText {
    color: var(--bs-body-color);
}

.cl-socialButtonsBlockButton:hover,
.cl-alternativeMethodsBlockButton:hover {
    background-color: var(--bs-tertiary-bg);
    box-shadow: none;
}

.cl-formFieldInputShowPasswordButton {
    color: var(--bs-secondary-color);
    background: transparent;
}

/* The primary button, in the brand green with DARK text in both themes, exactly
   like the Pro button in the header. Goblin green is a light yellow-green:
   white on it is about 1.9:1, which is unreadable, whereas #1c2a00 is near
   9:1. */
.cl-formButtonPrimary {
    background: var(--gt-goblin-green);
    color: #1c2a00;
    border: 0;
    box-shadow: none;
    text-transform: none;
    letter-spacing: normal;
}

.cl-formButtonPrimary:hover,
.cl-formButtonPrimary:focus {
    background: var(--gt-goblin-green-light);
    color: #1c2a00;
    box-shadow: none;
}

/* Clerk's spinner and icons inherit currentColor in most places, but the
   provider logos are images and need no help. */
.cl-spinner {
    color: currentColor;
}

/* --- UserProfile (the account settings page) ---------------------------- */

/* The main content pane is hardcoded white, which would sit as a white slab
   inside a dark page. */
.cl-scrollBox,
.cl-pageScrollBox,
.cl-navbar,
.cl-page {
    background: transparent;
    color: var(--bs-body-color);
}

/* Clerk renders some values (the username, the email address) in leaf elements
   carrying NO stable descriptor class, only build-generated hashes that change
   between releases and must not be targeted. Inheriting down from an ancestor
   that IS addressable is the only durable way to reach them: left alone they
   keep Clerk's literal dark default and vanish in dark mode.
   Declared before the link and badge rules below so those still win. */
.cl-profileSectionTitleText,
.cl-profileSectionItem,
.cl-profileSectionItem *,
.cl-profileSectionContent,
.cl-profileSectionContent *,
.cl-userPreviewMainIdentifier,
.cl-userPreviewTextContainer *,
.cl-navbarButtonText,
.cl-menuButton {
    color: var(--bs-body-color);
}

.cl-badge {
    color: var(--bs-body-color);
    background-color: var(--bs-tertiary-bg);
}

.cl-profileSection,
.cl-profileSectionItem {
    border-color: var(--bs-border-color);
}

/* Sidebar nav: our own hover/active treatment rather than Clerk's grey. */
.cl-navbarButton {
    color: var(--bs-body-color);
}

.cl-navbarButton:hover {
    background-color: var(--bs-tertiary-bg);
}

.cl-navbarButton.cl-active {
    background-color: rgba(151, 201, 6, 0.14);
    color: var(--bs-body-color);
}

/* "Update profile", "Add email address" and similar are actions, not primary
   buttons, and Clerk renders them as links. */
.cl-profileSectionPrimaryButton {
    color: var(--bs-link-color);
    background: transparent;
    box-shadow: none;
}

.cl-profileSectionPrimaryButton:hover {
    color: var(--bs-link-hover-color);
    background-color: var(--bs-tertiary-bg);
}

/* The Pro button.
   Deliberately NOT built on .theme-toggle-split like its neighbours: it is the
   one thing in the header we actually want people to notice, so it is solid
   goblin green and spans the full height of the two-row cluster beside it
   (align-items: stretch on the parent does the work). */
.gt-pro-btn {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.15rem;
    padding: 0.4rem 1rem;
    border-radius: 0.5rem;
    border: 1px solid var(--gt-goblin-green);
    background: linear-gradient(135deg, var(--gt-goblin-green-light) 0%, var(--gt-goblin-green) 100%);
    /* Dark text on a bright green fill in both themes: the gradient does not
       flip with the theme, so the text must not either. !important because the
       button is an <a> in the navbar, whose link colour would otherwise turn
       the label and icon link-blue on the green — most visible on the compact
       mobile copy, which is icon-only. The signed-in (account) variant below
       re-asserts its own colours over this. */
    color: #1c2a00 !important;
    text-decoration: none;
    white-space: nowrap;
    transition: filter 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
}

.gt-pro-btn:hover,
.gt-pro-btn:focus {
    color: #1c2a00 !important;
    text-decoration: none;
    filter: brightness(1.06);
    box-shadow: 0 2px 10px rgba(151, 201, 6, 0.45);
}

.gt-pro-btn .gt-pro-icon {
    font-size: 1.15rem;
    line-height: 1;
    color: inherit;
}

.gt-pro-btn .gt-pro-label {
    font-size: 0.95rem;
    font-weight: 700;
    line-height: 1.1;
}

/* Signed in and subscribed: the inverted treatment. Once there is nothing left
   to sell, the button stops shouting — a body-coloured fill with a green icon,
   clearly distinct from the loud green of the signed-out state. The colours use
   !important so they re-assert over the base .gt-pro-btn colour above (itself
   !important, to beat the navbar's link colour). */
.gt-pro-btn-account {
    background: var(--bs-body-bg);
    color: var(--bs-body-color) !important;
    border-color: var(--bs-border-color);
}

.gt-pro-btn-account:hover,
.gt-pro-btn-account:focus {
    color: var(--bs-body-color) !important;
    border-color: var(--gt-goblin-green);
    box-shadow: none;
}

.gt-pro-btn-account .gt-pro-icon {
    color: var(--gt-goblin-green);
}

/* Compact single-row variant sitting next to the mobile menu toggler. The full
   button is a tall two-line control; here it lines up beside the toggler, and
   the wrapper's align-items: stretch makes the two exactly the same height. */
.gt-pro-btn-compact {
    flex-direction: row;
    gap: 0.4rem;
    padding: 0.25rem 0.7rem;
}

.gt-pro-btn-compact .gt-pro-icon {
    font-size: 1rem;
}

.gt-pro-btn-compact .gt-pro-label {
    font-size: 0.9rem;
}

/* Below the navbar's xl breakpoint the header folds into the drop-down menu,
   which carries its own copy of the Pro button. The compact button beside the
   toggler already covers Pro there, so hide the in-menu copy to keep it on the
   page exactly once. Only the copy inside the collapse is hit; the compact one
   and the homepage's direct cluster live outside it and stay put. */
@media (max-width: 1199.98px) {
    .navbar-collapse .gt-pro-btn {
        display: none;
    }
}

/* Very narrow headers: drop to a single row and let the icon carry it. */
@media (max-width: 420px) {
    .gt-pro-btn {
        padding: 0.4rem 0.6rem;
    }

    .gt-pro-btn .gt-pro-label {
        display: none;
    }
}

/* Shared-list preview. Slightly wider than the export modal because it shows
   a nested list rather than a paragraph. */
.gt-receive-modal {
    max-width: 560px;
}

.gt-receive-preview {
    max-height: 40vh;
    overflow-y: auto;
    border: 1px solid var(--bs-border-color);
    border-radius: 0.375rem;
    padding: 0.75rem;
    background-color: var(--bs-tertiary-bg);
}

.gt-receive-tree {
    list-style: none;
    padding-left: 0;
    margin: 0;
}

.gt-receive-tree .gt-receive-tree {
    padding-left: 1.1rem;
    border-left: 1px solid var(--bs-border-color);
    margin-left: 0.35rem;
}

.gt-receive-tree li {
    padding: 0.15rem 0;
    line-height: 1.4;
    /* A stranger's text: wrap it rather than let a long unbroken string
       stretch the modal off-screen. */
    overflow-wrap: anywhere;
}

.gt-receive-emoji {
    margin-right: 0.4rem;
}

/* Template picker */
.gt-templates-list {
    max-height: 55vh;
    overflow-y: auto;
}

.gt-templates-heading {
    font-size: 0.8rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--bs-secondary-color);
    margin: 0.9rem 0 0.35rem;
}

.gt-templates-heading:first-child {
    margin-top: 0;
}

.gt-template-row {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    width: 100%;
    padding: 0.55rem 0.65rem;
    border: 1px solid var(--bs-border-color);
    border-radius: 0.375rem;
    background-color: var(--bs-body-bg);
    color: var(--bs-body-color);
    text-align: left;
    margin-bottom: 0.35rem;
}

.gt-template-row:hover,
.gt-template-row:focus {
    background-color: var(--bs-tertiary-bg);
    border-color: var(--gt-goblin-green);
}

.gt-template-emoji {
    font-size: 1.15rem;
    flex-shrink: 0;
}

.gt-template-name {
    flex-grow: 1;
    overflow-wrap: anywhere;
}

/* The history entry point: a plain icon tucked inside the input next to the
   mic, positioned by pro-history.js (left/top set inline). Not a bordered
   button — it lives among the input's own affordances. */
.gt-history-toggle {
    position: absolute;
    z-index: 99;
    padding: 0;
    border: 0;
    background: transparent;
    color: var(--bs-secondary-color);
    cursor: pointer;
    font-size: 0.95rem;
    line-height: 1;
}

.gt-history-toggle:hover,
.gt-history-toggle:focus {
    color: var(--bs-body-color);
}

/* History panel. A dropdown rather than a modal — you're dipping into it and
   coming straight back out, not making a decision. pro-history.js fixes it just
   under the button that opened it (top/left/max-height set inline), so it lands
   next to that button on any screen instead of a corner or a bottom sheet. */
.gt-history-panel {
    position: fixed;
    z-index: 1050;
    width: 22rem;
    max-width: calc(100vw - 1rem);
    overflow-y: auto;
    background-color: var(--bs-body-bg);
    border: 1px solid var(--bs-border-color);
    border-radius: 0.5rem;
    box-shadow: 0 10px 40px rgba(0, 0, 0, 0.15);
    padding: 0.75rem;
}

.gt-history-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 0.5rem;
}

.gt-history-message {
    color: var(--bs-secondary-color);
    font-size: 0.9rem;
    padding: 0.5rem 0;
}

.gt-history-row {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.1rem;
    width: 100%;
    padding: 0.45rem 0.55rem;
    border: none;
    border-radius: 0.375rem;
    background: transparent;
    color: var(--bs-body-color);
    text-align: left;
}

.gt-history-row:hover,
.gt-history-row:focus {
    background-color: var(--bs-tertiary-bg);
}

.gt-history-summary {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    line-height: 1.35;
    overflow-wrap: anywhere;
}

.gt-history-when {
    font-size: 0.78rem;
    color: var(--bs-secondary-color);
}

/* Narrow screens: the panel stays anchored to its button (positioned in JS),
   just capped to the viewport width so it never runs off the edge. */
@media (max-width: 575.98px) {
    .gt-history-panel {
        width: calc(100vw - 1rem);
    }
}

/* Step count, so the size of a template is obvious before opening it. */
.gt-template-count {
    flex-shrink: 0;
    font-size: 0.8rem;
    color: var(--bs-secondary-color);
    background-color: var(--bs-tertiary-bg);
    border-radius: 999px;
    padding: 0.05rem 0.5rem;
}

/* Loading Overlay Styles */
.loading-overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.7);
    z-index: 9999;
    display: none;
    align-items: center;
    justify-content: center;
}

.loading-overlay.show {
    display: flex;
}

.loading-overlay-content {
    background-color: var(--bs-body-bg);
    padding: 2rem;
    border-radius: 0.5rem;
    text-align: center;
    box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3);
    max-width: 90%;
}

.loading-spinner {
    width: 50px;
    height: 50px;
    margin: 0 auto 1.5rem;
    border: 4px solid var(--bs-border-color);
    border-top-color: var(--bs-primary);
    border-radius: 50%;
    animation: spin 0.8s linear infinite;
}

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

.loading-text {
    font-size: 1.1rem;
    margin: 0.5rem 0;
    color: var(--bs-body-color);
}

.loading-longer-text {
    display: none;
    font-size: 0.9rem;
    color: var(--bs-secondary-color);
    margin-top: 1rem;
}

.loading-cancel-btn {
    display: none;
    margin-top: 1.5rem;
    margin-left: auto;
    margin-right: auto;
    padding: 0.5rem 1.5rem;
    background-color: var(--bs-secondary-bg);
    color: var(--bs-body-color);
    border: 1px solid var(--bs-border-color);
    border-radius: 0.375rem;
    cursor: pointer;
    font-size: 0.95rem;
    transition: all 0.2s ease;
}

.loading-cancel-btn:hover {
    background-color: var(--bs-secondary-bg);
    border-color: var(--bs-border-color);
    opacity: 0.8;
    transform: translateY(-1px);
}

.loading-cancel-btn:active {
    transform: translateY(0);
}

/* Responsive adjustments for mobile */
@media (max-width: 768px) {
    .loading-overlay-content {
        padding: 1.5rem;
        max-width: 85%;
    }

    .loading-spinner {
        width: 40px;
        height: 40px;
        margin-bottom: 1rem;
    }

    .loading-text {
        font-size: 1rem;
    }

    .loading-cancel-btn {
        padding: 0.4rem 1.2rem;
        font-size: 0.9rem;
    }
}