:root {
    --brand-primary-text-colour: #333333;
    --bg-secondary-colour: white;
}

html {
    background-color: var(--page-bg-colour);
    background-image: var(--page-bg-image);
    font-family: var(--font-family);
    font-size: var(--font-size);
    font-weight: var(--font-weight);
}

body {
    color: var(--brand-primary-text-colour);
    margin: 0;
    padding: 0;
    overflow-x: hidden;
    flex-direction: row;
}

textarea {
    min-height: 110px;
}

h1, h2, h3, h4, h5, h6 {
    color: var(--header-colour);
}

.hide {
    display: none;
}

.font-sans {
    font-family: var(--font-family);
}

.p-4 {
    padding: 1rem;
}

.p-8 {
    padding: 2rem;
}

.px-8 {
    padding-right: 2rem;
    padding-left: 2rem;
}

.pb-8 {
    padding-bottom: 2rem;
}

.pt-8 {
    padding-top: 2rem;
}

.gap-2 {
    gap: 0.5rem;
}

.flex-none {
    flex: 0 0 auto
}

#toggle-sidebar a {
    height: 32px;
}

.toggle-btn {
    background: none;
    border: none;
    cursor: pointer;
    transition: transform 0.3s ease;
}

.sidebar.collapsed .toggle-btn .sidebar-item-icon {
    transform: rotate(180deg);
}

.sidebar-item a {
    border-left: 3px solid transparent;
    color: var(--sidebar-text-colour, #374151);
    border-radius: 8px;
    margin-left: 10px;
    margin-right: 10px;
    font-size: 14.5px;
}

.sidebar-item a:hover {
    /* Keep the resting text colour; just a translucent lift, a touch
       stronger than the workspace pill tint, and lighter than the solid
       brand wash of the selected state. */
    background-color: color-mix(in srgb, var(--sidebar-text-colour, #374151) 14%, transparent);
}

.sidebar-item.selected a {
    background-color: color-mix(in srgb, var(--brand-primary-colour) 20%, white);
    color: var(--brand-primary-colour);
    border-left: 3px solid var(--brand-primary-colour);
}

.sidebar {
    color: var(--sidebar-text-colour, #374151);
    min-width: max-content;
    max-width: max-content;
    transition: width 0.3s ease;
    overflow-y: auto;
    overflow-x: hidden;
    position: relative;
}

/* Optional decorative pattern behind the sidebar, chosen via the
   ui::sidebar-pattern brand setting (default off). Each pattern is a
   .sidebar-pattern--{value}::after overlay; the shared rules below set
   up the overlay layer and keep nav content above it. Add a new
   pattern by adding an option to the SidebarPattern setting + a
   matching ::after rule here. */
.sidebar.sidebar-pattern::after {
    content: '';
    position: absolute;
    inset: 0;
    min-height: 100%;
    pointer-events: none;
    z-index: 0;
}
.sidebar.sidebar-pattern > * {
    position: relative;
    z-index: 1;
}

/* Pattern: diagonal lines. Tint adapts to the sidebar text colour, so
   it reads on both light and dark sidebars. */
.sidebar.sidebar-pattern--diagonal-lines::after {
    background-image: repeating-linear-gradient(
        135deg,
        color-mix(in srgb, var(--sidebar-text-colour, #374151) 8%, transparent) 0 2px,
        transparent 2px 16px
    );
}

.sidebar-item-label {
    min-width: 120px;
    visibility: visible;
    opacity: 1;
    transition: opacity 0.3s ease, visibility 0s 0s;
}

.sidebar.collapsed .sidebar-item-label {
    display: none;
    transition: opacity 0.3s ease, visibility 0s 0.3s;
}

.sidebar.collapsed:hover .sidebar-item-label {
    display: unset;
}

.sidebar nav ul {
    list-style: none;
    padding: 0;
    margin: 0;
}

.sidebar nav .sidebar-item:hover {
    background-color: transparent;
}

/* ─────────────────────────────────────────────────────────────────
   Page chrome + scroll model.

   Goal: exactly ONE scrollable container in the page chrome chain,
   below the static header. The scroll lives on .main-sections so
   the page header (hero or in-page) and any domain sub-nav stay
   visible while content scrolls underneath. Sidebars are full-
   height columns that don't scroll with the content.

   DOM produced by layouts/page.blade.php + pages/sections.blade.php:

     .page-container (full-height flex column, no scroll)
       └── .main-panel (flex column, fills, no scroll)
             ├── .page-hero-banner  OR  .page-header   (static)
             ├── .page-nav         (domain sub-nav, optional, static)
             └── .page-content     (flex row when sidebars present,
                                    single column otherwise)
                   ├── aside.main-sidebar--left   (full height, optional)
                   ├── .main-sections             (THE scroll container)
                   │     ├── @stack('page-chrome')  (banners, alerts,
                   │     │                           notifications)
                   │     └── [sections]
                   └── aside.main-sidebar--right  (full height, optional)

   Why one scroll: a single source of truth for "where does the
   user's wheel event go" eliminates the common bug where two
   nested overflow regions trap scroll in the inner one. .main-
   sections is the only `overflow-y: auto` in this chain; everything
   above it caps its own height with `overflow: hidden` + flex sizing
   so children can't blow past their parent.
   ───────────────────────────────────────────────────────────────── */

/* Outer chrome — no scroll. The full-page flex column that holds
   the topbar, tenant banners, and .main-panel.

   overflow: hidden bounds the children's height. Tooltips / dropdowns
   from descendants that need to escape their parent's box use
   z-index + position: relative against later siblings (e.g. the
   .page-nav vs .page-content stacking); they don't extend outside
   .page-container's actual rectangle so this overflow doesn't clip
   them. Scroll lives on .main-sections only. */
.page-container {
    display: flex;
    flex-direction: column;
    flex-grow: 1;
    /* The page-container owns the vertical scroll by default, so the
       scrollbar sits at the screen edge while content stays centered
       (max-width on .main-panel). Pages that render an aside (sticky
       right rail, e.g. the code-generator chat) opt back into the
       inner-scroll chain via the :has() overrides below. */
    overflow-y: auto;
    min-height: 0;
}

/* Aside-bearing pages keep the original bounded inner-scroll chain so
   sticky rails / composers stay pinned on-screen. */
.page-container:has(.main-sidebar) {
    overflow: hidden;
}

/* Main panel — holds the page header (hero or in-page), optional
   domain sub-nav, and the scrollable .page-content. Flex column;
   itself does not scroll.

   overflow: hidden is REQUIRED here to bound the children's height —
   without it, a tall .page-content (with sticky asides like the
   iterate chat rail) grows past the viewport instead of constraining
   itself to .main-panel's flex height. That would push the rail's
   composer offscreen.

   The domain tab-bar dropdown stacking is handled by .page-nav
   (z-index: 50) + .page-content (z-index: 0) so dropdowns paint
   above content even though .main-panel clips at its own bounds —
   the dropdown's actual rectangle stays within .main-panel's box. */
.main-panel {
    flex: 1 0 auto;
    display: flex;
    flex-direction: column;
    width: 100%;
    max-width: var(--content-max-width, 1280px);
    margin: 0 auto;
    transition: margin-left 0.3s ease, max-width 0.3s ease;
}

/* When an aside is present, the panel is height-bounded again so its
   inner .page-content/.main-sections own the scroll (sticky rails). */
.page-container:has(.main-sidebar) .main-panel {
    flex: 1;
    min-height: 0;
    overflow: hidden;
}

/* Domain sub-navigation (e.g. tabs across a domain landing page).
   Static — does not scroll with content.

   Class name is .page-domain-nav (NOT .page-nav, which is a
   pre-existing class in this stylesheet with overflow: hidden
   for a different horizontally-scrollable nav strip). The unique
   name is what lets the inner topbar's overflow "..." dropdown
   paint correctly — overflow defaults to visible. */
.page-domain-nav {
    flex-shrink: 0;
    margin-top: 1.5rem;
}

/* The flex container that holds the sidebar columns + main sections.
   Fills the remaining vertical space below the header chrome.
   - With sidebars present: becomes a flex row (sidebars + main).
   - Without sidebars: single column, .main-sections fills.
   Itself does not scroll — overflow lives on .main-sections. */
.page-content {
    flex: 1 0 auto;
    display: flex;
    flex-direction: row;
}

/* Aside-bearing pages: bound the row + delegate scroll to .main-sections. */
.page-container:has(.main-sidebar) .page-content {
    flex: 1;
    min-height: 0;
    overflow: hidden;
}

/* The scrollable main content column. Padding gives content
   breathing room from the column edges; reduced horizontally when
   an aside is adjacent (each aside provides its own inner padding
   so we don't need to double up).

   Top padding (1rem) lifts the first widget off the page header /
   tab-bar border so content doesn't touch the chrome. Less than
   bottom (1.5rem) because the bottom benefits from extra breathing
   room when scrolled to the end. */
.main-sections {
    flex: 1;
    min-width: 0;
    padding: 1rem 2rem 1.5rem;
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

/* Aside-bearing pages: .main-sections owns the vertical scroll. */
.page-container:has(.main-sidebar) .main-sections {
    min-height: 0;
    overflow-y: auto;
}
/* When a left aside sits to the LEFT of .main-sections, drop the
   main-sections' left padding (aside has padding-right of its own). */
.page-content:has(> .main-sidebar--left) > .main-sections {
    padding-left: 1rem;
}
.page-content:has(> .main-sidebar--right) > .main-sections {
    padding-right: 1rem;
}

/* Sidebars — full-height static columns. Each aside is a flex
   column with its own (optional) internal scroll. The framework
   default is 30vw wide; --right modifier narrows to 420px.

   Padding mirrors .main-sections so sidebar content has the same
   breathing room as the main column and doesn't kiss the screen
   edge or the scroll gutter. Asymmetric horizontal padding (more
   on the OUTSIDE) keeps the visual balance — left aside has more
   padding-left, right aside has more padding-right.

   Top padding (1rem) matches .main-sections so all three columns
   start at the same baseline below the page header / tab-bar
   border. */
.main-sidebar {
    flex: 0 0 30vw;
    min-height: 0;
    align-self: stretch;
    display: flex;
    flex-direction: column;
    overflow-y: auto;
    padding: 1rem 1rem 1.5rem;
}
.main-sidebar--left  { padding-left: 2rem; }
.main-sidebar--right { padding-right: 2rem; }

@media (min-width: 640px) {
    /* Order the flex children: left aside → main-sections → right aside. */
    .main-sidebar--left  { order: 0; }
    .main-sections       { order: 1; }
    .main-sidebar--right {
        order: 2;
        flex-basis: 420px;
    }

    /* Legacy: a .main-sidebar with no left/right modifier (used by
       any consumer that bypasses the sections template and writes
       the aside directly into a custom view). Kept floating left to
       match the historical behaviour these consumers depend on. */
    .main-sidebar:not(.main-sidebar--left):not(.main-sidebar--right) {
        float: left;
        margin-right: 2rem;
    }
}

/* Mobile: collapse to a single vertical stack. Asides become full-
   width blocks above/below the sections. The single-scroll model
   still holds — only .main-sections scrolls. */
@media (max-width: 639px) {
    .page-content {
        flex-direction: column;
        overflow-y: auto;
    }
    .main-sidebar {
        flex: 0 0 auto;
        margin-bottom: 1rem;
        overflow-y: visible;
    }
    .main-sections {
        overflow-y: visible;
    }
}

.content-panel {
    overflow-x: visible;
}

.topbar {
    padding-left: 10px;
    padding-right: 10px;
    display: flex;
    position: sticky;
    top: 0px;
    background-color: white;
    min-height: 65px;
    justify-content: space-between;
    border-bottom-width: 1px;
    align-items: center;
    z-index: 1000;
}

.nav-link {
    border-bottom: 3px solid transparent;
}

.nav-link:hover,
.nav-link:focus {
    border-bottom: 3px solid var(--brand-primary-colour);
    background-color: rgba(105, 30, 218, 0.3);
    color: var(--brand-primary-colour);
    outline: none;
}

.nav-link.active {
    border-bottom: 3px solid var(--brand-secondary-colour);
}

.topbar-nav {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    height: 100%;
}

.topbar-left,
.topbar-right  {
    height: 100%;
}

.topbar-nav a {
    color: #333333BB;
    text-decoration: none;
    font-size: 1em;
    transition: color 0.3s;
    border-bottom: 2px solid white;
}

.topbar-nav a.active {
    border-bottom: 2px solid var(--brand-secondary-colour);
    font-weight: bold;
}

.topbar-nav a:hover {
    color: var(--brand-secondary-colour);
}

.topbar-title {
    font-weight: bold;
}

.subnav {
    padding-left: 10px;
    padding-right: 10px;
    display: flex;
    position: sticky;
    top: 0px;
    background-color: var(--bg-primary-colour);
    justify-content: space-between;
    border-bottom-width: 1px;
    align-items: center;
}

.subnav a {
    border-bottom: 0;
    margin-top: 5px;
    margin-bottom: 5px;
    padding: 0px;
    padding-right: 1rem;
    padding-left: 1rem;
}

.subnav a:not(:last-child) {
    border-right: 1px solid #a0a0a0;
}

.subnav a.active {
    border-bottom: 0;
    color: var(--brand-primary-colour);
    font-weight: 600;
}

.page-nav {
    margin-left: 0px;
    white-space: nowrap;
    overflow-x: hidden;
    overflow-y: hidden;
}

.site-nav {
    background-color: white;
}

.site-header {
    color: var(--brand-primary-colour);
    font-size: 1.1rem;
}

@media screen and (max-width: 600px) {
    .pt-8 {
        padding-top: 1rem;
    }
    
    .px-8 {
        padding-right: 1rem;
        padding-left: 1rem;
    }

    .gap-6 {
        gap: 1rem;
    }

    .page-container {
        padding-bottom: 70px;
    }

    .site-header {
        gap: 1rem;
    }

    .site-header h2 {
        color: var(--text-primary-colour);
    }

    .sidebar {
        min-width: 80vw;
        max-width: 80vw;
        position: fixed;
        z-index: 10100;
        top: 0;
        bottom: 0;
        left: 0;
        height: 100vh;
        box-shadow: 4px 0 20px rgba(0, 0, 0, 0.15);
    }

    /* When the sidebar drawer is open on mobile, hide the bottom
       tab bar so it doesn't peek through to the right of the drawer. */
    body:has(#sidebar:not(.hidden)) .mobile-tab-bar {
        display: none;
    }

    .sidebar.collapsed {
        display: none;
    }

    .sidebar.collapsed .sidebar-item-label {
        display: unset;
    }

    .page-container {
        max-width: 100vw;
    }

    .page-nav {
        margin-left: 0px;
        white-space: nowrap;
        overflow-x: scroll;
    }

    .page-nav {
        overflow: auto;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none; 
        -ms-overflow-style: none;
    }

    .page-nav ::-webkit-scrollbar {
        display: none;
    }

    /* Page-header mobile overrides moved to the end of this file — they
       must come AFTER the base .page-header__* rules so CSS source order
       lets them win. See "Page-header mobile (post-base overrides)". */

    .page-fab.link-button {
        aspect-ratio: 1/1;
        border-radius: 50% !important;
        align-content: center;
        outline: 4px solid color-mix(in oklab, #fff 85%, transparent);
    }

    .page-fab-overlay {
        position: fixed;
        background-color: #eee;
        top: 0px;
        left: 0px;
        width: 100%;
        height: 100%;
        opacity: 0.5;
        z-index: -1;
        display: none;
    }

    #action-toggle:checked ~ .page-fab-overlay {
        display: block;
    }

    .page-actions {
        position: fixed;
        bottom: 110px;
        right: 16px;
        z-index: 100;
        flex-direction: column-reverse;
        align-items: end;
    }

    #action-toggle ~ a,
    #action-toggle ~ .dropdown {
        display: none;
    }

    #action-toggle:checked ~ a,
    #action-toggle:checked ~ .dropdown {
        display: flex;
    }

    main,
    .page-container {
        padding-bottom: 60px;
    }

    .content {
        padding-bottom: 50px;
    }

    .main-nav {
        overflow: hidden;
        margin-right: 1rem;
    }

    .main-nav-links {
        position: fixed;
        right: 0px;
        left: 0px;
        bottom: 0px;
        margin: 0px;
        background-color: white;
        border-top: 1px solid #ddd;
        gap: 0px;
        height: 60px;
    }

    .main-nav-links a {
        display: flex;
        flex-direction: column;
        flex: 1;
        font-size: small;
        gap: 0px;
        padding-top: 10px;
        padding-right: 0px;
        padding-left: 0px
    }
}

/* Tables */
.table-header {
    background-color: #F0EDEE;
}

tfoot tr {
    background-color: #F0EDEE;
}

th {
    text-align: left;
    padding: 0.5rem;
    text-transform: uppercase;
}

.log-table td,
.log-table th {
    max-width: 200px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.table-frame {
    overflow-x: auto;
}

.table-action {
    display: inline-block;
}

/* Fixed column layout — opt-in via `data-table--fixed` when a table
   declares explicit column widths (BaseColumn::width). Desktop only:
   the mobile @media block below renders the table as a card stack
   where a fixed layout / colgroup widths make no sense, so the rule
   is scoped above the 600px breakpoint. */
@media screen and (min-width: 601px) {
    table.data-table--fixed {
        table-layout: fixed;
    }
}

/* Responsive styles for small screens — render data tables as a
   stack of cards, one card per row. Each cell becomes a label/value
   line; the action column floats to the top-right of the card. */
@media screen and (max-width: 600px) {
    /* Side gutters for the card stack — the desktop table is full-bleed
       inside the section card, but the mobile cards look better inset
       from the section edge. Padding on the container (not the cards)
       so the search/header toolbar above lines up with the cards. */
    .table-container {
        padding-left: 0.75rem;
        padding-right: 0.75rem;
    }

    /* `display: block` on the table is essential — a `display: table`
       element shrink-wraps to its content, and any `<colgroup>` width
       (emitted by `data-table--fixed`) would otherwise collapse the
       card stack to a fraction of the screen. As a block the table and
       its `<colgroup>` are inert, so the cards span the full width. */
    .responsive-table {
        display: block;
        width: 100%;
        background: transparent !important;
        box-shadow: none !important;
        border-spacing: 0 0.75rem;
        border-collapse: separate;
    }

    .responsive-table colgroup {
        display: none;
    }

    .responsive-table thead {
        display: none;
    }

    .responsive-table tbody {
        display: block;
        width: 100%;
        background: transparent !important;
    }

    .responsive-table tr {
        display: block;
        position: relative;
        background: #fff;
        border: 1px solid #e5e7eb;
        border-radius: 0.75rem;
        padding: 0.875rem 1rem;
        margin-bottom: 0.75rem;
        box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
    }

    .responsive-table td {
        display: flex;
        align-items: flex-start;
        gap: 0.5rem;
        border: none;
        padding: 0.25rem 0;
        position: relative;
        /* `min-width: 0` lets the cell shrink below its content so the
           value wraps at word boundaries; `overflow-wrap: break-word`
           only kicks in for genuinely unbreakable strings (long URLs,
           UUIDs) — it must NOT be `anywhere`, which breaks ordinary
           words mid-character. */
        min-width: 0;
        width: 100%;
        max-width: 100%;
        box-sizing: border-box;
        overflow-wrap: break-word;
        word-break: break-word;
    }

    /* Anything the cell renders — text, links, badges, a nested
       <span> from an HtmlColumn — is clamped to the cell width and
       breaks unbreakable strings (emails, UUIDs) rather than forcing
       the card wide. `min-width: 0` is needed on flex/inline children
       so they can shrink below their intrinsic content width. */
    .responsive-table td > * {
        min-width: 0;
        max-width: 100%;
        overflow-wrap: break-word;
        word-break: break-word;
    }

    /* Label column: a fixed-basis flex item that does NOT grow — it
       takes exactly ~6.5rem and yields the rest of the row to the
       value, so the value text uses the full remaining width instead
       of shrink-wrapping and wrapping awkwardly after a word or two.
       Top-aligned so a multi-line value doesn't drag the label down. */
    .responsive-table td::before {
        content: attr(data-label);
        font-weight: 600;
        font-size: 0.8125rem;
        color: #6b7280;
        flex: 0 0 6.5rem;
        min-width: 0;
        align-self: flex-start;
        overflow-wrap: break-word;
        word-break: break-word;
    }

    /* UserColumn cells render an avatar that is taller than a single
       line of text. Centre the label (and the cell's flex items) so
       the label lines up with the name rather than the avatar top. */
    .responsive-table td.user-column-cell {
        align-items: center;
    }

    .responsive-table td.user-column-cell::before {
        align-self: center;
    }

    /* Action column docks to the bottom of the card as a full-width
       footer row, separated by a hairline divider. Negative margin
       breaks out of the card's `0.875rem 1rem` padding so the divider
       and footer span edge-to-edge. The cell carries `.fit-content`
       (width:1px) and `min-width:100px` from desktop — override both
       so the footer can stretch full-width on mobile. */
    .responsive-table td.table-actions-column,
    .responsive-table td[data-label="Actions"] {
        /* Do NOT set an explicit width. As a block-level flex element
           inside the card, `width: auto` fills the card's content box
           exactly; the `-1rem` side margins then extend it precisely
           to the card border on each side. An explicit `calc(100% +
           2rem)` would over-extend (100% is the content box, already
           inside the padding) and push the divider past the edge.
           `box-sizing: border-box` keeps the 1rem padding inside that
           width so the pills wrap instead of bleeding off-screen. */
        box-sizing: border-box;
        width: auto !important;
        /* The base `.responsive-table td` rule clamps every cell to
           `max-width: 100%` (= the card content box). The action cell
           must break OUT past that to the card border, so the clamp
           has to be lifted here or the divider stops short on the
           right. */
        max-width: none !important;
        min-width: 0 !important;
        margin: 0.625rem -1rem -0.875rem;
        padding: 0.625rem 1rem;
        border-top: 1px solid #f3f4f6;
        /* When the pills wrap, `flex-start` keeps the wrapped row left
           aligned and the rows packed — a lone wrapped pill hanging
           off the right edge (from `flex-end`) looks unbalanced. */
        justify-content: flex-start;
        flex-wrap: wrap;
        gap: 0.375rem;
        white-space: normal;
    }

    .responsive-table td.table-actions-column::before,
    .responsive-table td[data-label="Actions"]::before {
        display: none;
    }

    /* Promote each `<div class="table-action">` (16x16 icon-only on
       desktop) into a proper labelled pill button on mobile. The
       action's `title` attribute on the inner `<a>` carries the label
       — surface it via a `::after` pseudo-element. */
    .responsive-table td.table-actions-column .table-action,
    .responsive-table td[data-label="Actions"] .table-action {
        width: auto;
        height: auto;
        display: inline-flex;
        align-items: center;
    }

    .responsive-table td.table-actions-column .table-action > a,
    .responsive-table td[data-label="Actions"] .table-action > a {
        display: inline-flex;
        align-items: center;
        gap: 0.3125rem;
        padding: 0.375rem 0.625rem;
        background: #f3f4f6;
        color: #374151;
        border-radius: 9999px;
        font-size: 0.75rem;
        font-weight: 500;
        line-height: 1;
        /* Pills can shrink below their content and clip the label so
           a row of 3+ actions wraps rather than overflowing the card. */
        max-width: 100%;
        white-space: nowrap;
    }

    .responsive-table td.table-actions-column .table-action > a > svg,
    .responsive-table td[data-label="Actions"] .table-action > a > svg {
        width: 0.875rem;
        height: 0.875rem;
        flex-shrink: 0;
    }

    .responsive-table td.table-actions-column .table-action > a::after,
    .responsive-table td[data-label="Actions"] .table-action > a::after {
        content: attr(title);
    }

    /* Hide cells with no rendered value so empty fields don't push
       the card height. Targets cells whose only content is whitespace
       (CSS can't see "empty after render", so this is best-effort:
       visually-empty cells keep showing the label — packages that
       want a tighter look can null out empty cells server-side). */
    .responsive-table td:empty {
        display: none;
    }

    /* Hide cells with no column title — UUID copy-buttons and other
       label-less utility columns. They're noise in the card layout. */
    .responsive-table td[data-label=""] {
        display: none;
    }

    /* Hide the "N results" count from the search header on mobile —
       saves vertical space; the count is implicit from the card list. */
    .table-search-container [data-table-result-count] {
        display: none !important;
    }

    /* Compact the search input vertically so it doesn't dwarf the
       inline action button next to it. */
    .table-search-container input[type="text"] {
        padding-top: 0.5rem !important;
        padding-bottom: 0.5rem !important;
        font-size: 0.875rem !important;
    }

    /* Inline action button ("+ Create X") next to the search input
       is `<a class="link-button uppercase tracking-widest …">`.
       Parent flex row uses `items-stretch` which makes the button
       grow to match the search input height — pin it to its own
       content height and shrink padding/font for proportional sizing.
       Anchor to the top of its flex row so when the filters wrap to
       a new line below the search input, the button stays aligned
       with the search bar instead of floating between the two. */
    .table-search-container a.link-button.uppercase,
    .table-search-container a.link-button.uppercase:hover,
    .table-search-container a.link-button.uppercase:focus,
    .table-search-container a.link-button.uppercase:active {
        padding: 0.5rem 0.875rem !important;
        font-size: 0.75rem !important;
        border-radius: 9999px !important;
        align-self: flex-start !important;
        height: auto !important;
        margin-top: 0.25rem !important;
        background-color: var(--button-primary-bg) !important;
        color: var(--button-primary-fg) !important;
    }

    /* Mobile quick-filter row — the search blade renders a dedicated
       `.quick-filter-mobile` block at full row width below the search
       + action button. Drop the rounded-capsule chrome so pills stand
       alone, and pin active/inactive colours across hover/focus/active
       so a tap doesn't flash to slate-grey. */
    .quick-filter-mobile .quick-filter-pills {
        background: transparent !important;
        border: 0 !important;
        padding: 0 !important;
        gap: 0.375rem !important;
    }
    .quick-filter-mobile .quick-filter-pills > a:not([style*="background-color"]),
    .quick-filter-mobile .quick-filter-pills > a:not([style*="background-color"]):hover,
    .quick-filter-mobile .quick-filter-pills > a:not([style*="background-color"]):focus,
    .quick-filter-mobile .quick-filter-pills > a:not([style*="background-color"]):active {
        background: #f3f4f6 !important;
        color: #374151 !important;
        border: 1px solid #e5e7eb !important;
    }
    /* Active pill border to match the inactive ones — keeps the
       circular outline consistent so pills don't shift size when
       toggling state. */
    .quick-filter-mobile .quick-filter-pills > a[style*="background-color"] {
        border: 1px solid transparent !important;
    }
    .quick-filter-mobile .quick-filter-pills > a[style*="background-color"],
    .quick-filter-mobile .quick-filter-pills > a[style*="background-color"]:hover,
    .quick-filter-mobile .quick-filter-pills > a[style*="background-color"]:focus,
    .quick-filter-mobile .quick-filter-pills > a[style*="background-color"]:active {
        background-color: var(--button-primary-bg, #691EDA) !important;
        color: var(--button-primary-fg, #fff) !important;
    }

    /* Mobile icon buttons (`+` action, funnel toggle) — circular
       36px tap targets with state-pinned colours so a tap doesn't
       flash to a different background.
         --primary: brand-coloured fill, white icon
         --neutral: grey background, grey icon */
    .mobile-icon-btn,
    button.mobile-icon-btn {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 2.25rem;
        height: 2.25rem;
        border-radius: 9999px !important;
        flex-shrink: 0;
        transition: background-color 0.15s, color 0.15s;
    }
    .mobile-icon-btn--primary,
    .mobile-icon-btn--primary:hover,
    .mobile-icon-btn--primary:focus,
    .mobile-icon-btn--primary:active {
        background-color: var(--button-primary-bg, #691EDA) !important;
        color: var(--button-primary-fg, #fff) !important;
        border: 0 !important;
    }
    .mobile-icon-btn--neutral,
    .mobile-icon-btn--neutral:hover,
    .mobile-icon-btn--neutral:focus,
    .mobile-icon-btn--neutral:active {
        background-color: #f3f4f6 !important;
        color: #6b7280 !important;
        border: 1px solid #e5e7eb !important;
    }

    /* Pagination — restyled as a compact pill row. The "Showing X
       of Y" sentence drops below the page-number row, page numbers
       become circular tap targets, the active page is filled with
       the brand colour, and the prev/next chevrons sit at the row
       edges so they don't wrap to a new line on their own. */
    .paginator {
        flex-direction: column-reverse;
        gap: 0.75rem;
        align-items: center;
    }
    .paginator > div {
        font-size: 0.75rem;
    }
    .paginator > nav {
        flex-wrap: nowrap;
        justify-content: center;
        gap: 0.25rem !important;
        max-width: 100%;
    }
    .paginator > nav > a,
    .paginator > nav > svg {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        min-width: 2rem;
        height: 2rem;
        padding: 0 0.5rem;
        border-radius: 9999px;
        font-size: 0.875rem;
        color: #374151;
    }
    .paginator > nav > a:hover {
        background: #f3f4f6;
    }
    .paginator > nav > a.active-page {
        background: var(--button-primary-bg);
        color: var(--button-primary-fg, #fff) !important;
    }
    .paginator > nav > svg {
        color: #9ca3af;
    }

    /* Global guard against horizontal overflow on mobile — any child
       that exceeds the viewport width clamps to it. Tables wrapped in
       `.table-frame` already scroll their own overflow on desktop;
       on mobile we render as cards so the desktop scroll is moot. */
    html, body {
        max-width: 100vw;
        overflow-x: hidden;
    }
    .table-frame {
        overflow-x: visible;
    }

    /* Page-tab nav (domainTabs) — cap visible tabs at 3 on mobile and
       push the rest into the More dropdown. The Alpine `domainTabs`
       component normally measures tab widths and hides those that
       don't fit; on mobile we want a deterministic 3-up layout. The
       `tab-overflow.js` hijack reads which tabs are actually hidden
       (post-CSS) and writes the dropdown contents accordingly so the
       strip and dropdown can never overlap. */
    nav[x-data*="domainTabs"] [x-ref="tabContainer"] {
        gap: 0 !important;
        flex: 1 1 auto !important;
        width: 100% !important;
    }
    nav[x-data*="domainTabs"] [x-ref="tabContainer"] a[data-tab-item]:nth-of-type(n+4) {
        display: none !important;
    }
    nav[x-data*="domainTabs"] [x-ref="tabContainer"] a[data-tab-item]:nth-of-type(-n+3) {
        display: flex !important;
        flex: 1 1 0 !important;
        justify-content: center !important;
    }
    nav[x-data*="domainTabs"] [x-ref="moreButton"] {
        flex: 0 0 auto !important;
        margin-left: auto !important;
    }
    nav[x-data*="domainTabs"] [x-ref="tabContainer"]:has(a[data-tab-item]:nth-of-type(4)) [x-ref="moreButton"] {
        display: flex !important;
    }

    /* Empty page-header (showHeader true but title in topbar) still
       renders an empty flex div with whitespace/blade comments —
       :empty won't match, so collapse it when it has no element
       children. */
    .page-header:not(:has(> *)) {
        display: none !important;
    }
    /* When the page-header only holds an actions block (no title,
       no description) it still adds 16px `pb-4` above the tabs.
       Strip that bottom padding on mobile — the FAB/actions float
       instead of pushing layout space. */
    .page-header > .pb-4,
    .page-header > div[class*="pb-4"] {
        padding-bottom: 0 !important;
    }
}

.fit-content {
    white-space: nowrap;
    width: 1px;
}

.table-actions-column {
    white-space: nowrap;
    width: 1px;
    min-width: 100px;
}

.quote {
    border-left: 3px solid var(--brand-primary-colour);
    padding-left: 1rem;
}

.grid-cols-4 {
    grid-template-columns: repeat(4,minmax(0,1fr));
}

.grid-container {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
}

@media (max-width: 600px) {
    .grid {
        grid-template-columns: 1fr; 
    }
  
    .grid > * {
        min-width: 100%;
    }
}

.card {
    background-color: var(--content-bg-colour);
    background-image: var(--content-bg-image);
    border-radius: 5px;
    padding: 2rem;
}

.card-icon {
    width: 2rem;
    height: 2rem;
    color: var(--brand-secondary-colour);
}

.oneline {
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    display: inline-block;
}

.mx-16 {
    margin-right: 4rem;
    margin-left: 4rem;
}

.pickr {
    border: 1px solid grey;
    box-shadow: 0 0 0 1px white;
    display: inline-block;
    border-radius: 3px;
}

.pickr .pcr-button{
    position: unset;
}

.pcr-color-preview button {
    border-radius: 0px !important;
}

.button-group {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

button.bg-red-600 {
    background-color: var(--button-danger-bg);
    color: var(--button-danger-fg);
}

button.bg-gray-800 {
    background-color: var(--button-primary-bg);
    color: var(--button-primary-fg);
}

a.bg-gray-800 {
    background-color: var(--button-primary-bg);
    color: var(--button-primary-fg);
}

button.bg-white {
    background-color: var(--button-secondary-bg);
    color: var(--button-secondary-fg);
}

.notice {
    background-color: #fffdd0;
    align-items: center;
    gap: 0.5rem;
    border-bottom: 1px solid #e5e7eb;
}

.tile {
    display: flex;
    background-color: var(--content-bg-colour);
    background-image: var(--content-bg-image);
    border-radius: 12px;
    overflow: hidden;
    border: 1px solid #ddd;
}

.left-section {
    background-color: var(--brand-primary-colour);
    width: 120px;
    display: flex;
    justify-content: center;
    align-items: center;
    background: linear-gradient(rgba(105, 30, 218, 0.3), rgba(105, 30, 218, 0.3)), url(http://portal.docker.localhost/img/Sop.png);
    background-repeat: no-repeat;
    background-size: cover;
}

.progress-circle {
    width: 70px;
    height: 70px;
    border-radius: 50%;
    background: radial-gradient(circle closest-side, var(--brand-primary-colour) 80%, transparent 81%),
                conic-gradient(#26c6da 0% 30%, #e0e0e0 30% 100%);
    display: flex;
    justify-content: center;
    align-items: center;
    color: white;
    font-size: 14px;
    font-weight: bold;
    position: relative;
}

.progress-circle::after {
    width: 50px;
    height: 50px;
    border-radius: 50%;
    background-color: white;
    display: flex;
    justify-content: center;
    align-items: center;
    color: white;
    font-size: 14px;
    font-weight: bold;
    position: relative;
}

.progress-circle span {
    position: absolute;
}

.right-section {
    padding: 20px;
    display: flex;
    flex-direction: column;
    flex: 1;
}

.right-section h3 {
    margin: 0;
    color: #6a1b9a; /* Purple text */
    font-size: 18px;
}

.right-section p {
    margin: 10px 0 0;
    color: #666666; /* Light gray text */
    font-size: 14px;
}

.arrow-button {
    align-self: flex-end;
    background-color: #26c6da; /* Teal button */
    color: white;
    width: 35px;
    height: 35px;
    border-radius: 50%;
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: 16px;
    margin-top: 20px;
    cursor: pointer;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}

.arrow-button:hover {
    background-color: #1b9db4; /* Darker teal on hover */
}

.choices {
    margin-bottom: 0px;
    border-radius: .375rem;
    --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);
    --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);
    box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}

.choices__inner {
    /* margin-top: 0.25rem; */
    background-color: white;
    padding: 6px 6px 3.75px;
    border: 1px solid #ddd;
    border-radius: 5px;
    height: 42px;
    min-height: 42px;
}

.choices__input {
    margin-bottom: 0px;
    background-color: white;
}

.choices[data-type*=select-multiple] .choices__button, .choices[data-type*=text] .choices__button {
    border-left: none;
}

.choices__button {
    height: 24px !important; 
    width: 24px !important;
}

.is-disabled .choices__button {
    display: none;
}

.choice-element {
    max-height: 37px;
}

select.choice-element {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    opacity: 0;
    z-index: 0; /* Put it behind */
    pointer-events: none;
}

.choices__list--multiple .choices__item {
    color: var(--text-secondary-colour);
    background-color: var(--brand-secondary-colour);
    border: unset;
}

.choices__input:focus {
    box-shadow: unset;
}

.choices__list--dropdown, .choices__list[aria-expanded] {
    z-index: 100;
}

.visibility-hidden {
    visibility: hidden;
}

.information-container.wrapper {
    display: none;
}

/* Toogle Button */
.toggle-container {
    display: flex;
    align-items: center;
    gap: 10px;
}

.toggle-label {
    display: inline-block;
    width: 35px;
    height: 18px;
    background: grey;
    border-radius: 25px;
    position: relative;
    cursor: pointer;
    transition: background 0.3s ease;
}

.toggle-label::before {
    content: "";
    width: 14px;
    height: 14px;
    background: white;
    position: absolute;
    top: 2px;
    left: 2px;
    border-radius: 50%;
    transition: transform 0.3s ease;
}

.toggle-checkbox {
    display: none;
}

.toggle-checkbox:checked + .toggle-label {
    background: var(--brand-secondary-colour);
}

.toggle-checkbox:checked + .toggle-label::before {
    transform: translateX(15px);
}

/* Editing CSS */
.editing-toolbar {
    display: none;
}

.ql-editor {
    font-family: var(--font-family);
    font-size: var(--font-size);
    padding: 0px;
}

.html-editor .ql-editor {
    padding: 1rem;
}

.editing .editing-toolbar {
    position: absolute;
    top: 8px;
    right: 8px;
    left: auto;
    transform: none;
    background: #f3f4f6;
    border: 1px solid #e5e7eb;
    border-radius: 10px;
    padding: 2px;
    display: flex;
    align-items: center;
    gap: 2px;
    z-index: 15;
}

/* Compact, icon-only action buttons. The visible label is dropped in
   favour of title/aria-label tooltips so the bar takes minimal space. */
.editing .editing-toolbar .tool-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    padding: 0;
    border: none;
    background: transparent;
    border-radius: 7px;
    color: #4b5563;
    cursor: pointer;
    transition: background-color 0.12s ease, color 0.12s ease;
}

.editing .editing-toolbar .tool-btn:hover {
    background: #e5e7eb;
    color: #111827;
}

.editing .editing-toolbar .tool-btn .tool-icon {
    display: inline-flex;
    pointer-events: none;
}

.editing .editing-toolbar .move-handle {
    cursor: move;
}

/* Thin separator between the move handle and the action icons. */
.editing .editing-toolbar .tool-divider {
    width: 1px;
    align-self: stretch;
    margin: 4px 2px;
    background: #d1d5db;
}

.editing .ql-editor::before {
  content: "";
  position: absolute;
  top: -5px;
  left: -5px;
  right: -5px;
  bottom: -5px;
  border: 2px dotted var(--brand-secondary-colour);
  pointer-events: none; /* Ensures the pseudo-element doesn't block interactions */
}

.ql-tooltip {
    z-index: 100;
}

/* Tables */
th, td {
    border: 1px solid #ddd; /* Light grey border */
    padding: 8px;
    text-align: left;
    border-right: none;
    border-left: none;
}

th:first-child,
td:first-child {
    border-left: none;
}

th:last-child,
td:last-child {
    border-right: none;
}

tbody tr:hover {
    background-color: #F7F3FD;
}

/* Widgets */
.widget {
    border: 1px solid;
    border-color: var(--content-border-colour);
    box-sizing: content-box;
    border-radius: 12px;
    position: relative;
    background-color: var(--content-bg-colour);
    background-image: var(--content-bg-image);
}

@media screen and (max-width: 600px) {
    .widget-search {
        border: 0px;
    }

    .widget-search .form-actions {
        display: none;
    }

    .widget-search {
        background-color: transparent;
    }

    .widget-search form.advanced {
        background-color: white;
        border: 1px;
    }

    .widget-search form:not(.advanced) .field {
        padding-right: 0px;
        padding-left: 0px;
        padding-bottom: 0px;
        padding-top: 0.5rem;
    }
}

.widget.disabled {
    opacity: 0.7;
}

.widget-header {
    margin-bottom: 20px;
}

.widget h2 {
    color: #333333;
    font-weight: 900;
    font-size: 20px;
    line-height: 24px;    
}

.add-widget {
    display: none;
    flex-grow: 1;
    height: 1.5rem; 
    position: relative;
    background-color: #C7F4F3;
    margin-bottom: 1rem;
}

.add-widget::before {
    content: '';
    position: absolute;
    top: 50%; 
    left: 0;
    width: 100%;
    border-top: 2px dashed #1ACBB6;
    z-index: 1; 
}

.editing .add-widget {
    display: block;
}

.plus {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 1.5rem;
    height: 1.5rem;
    transform: translate(-50%, -50%); 
    z-index: 20; 
    color: #1ACBB6;
    background-color: white;
    border-radius: 50%;
    border: 1px solid #1ACBB6;
}

/* Forms */
fieldset {
    position: relative;
}

.form-actions {
    border-bottom-right-radius: 11px;
    border-bottom-left-radius: 11px;
}

.form-status {
    background-color: white;
    border: 1px solid #D0CCD5;
    padding: 5px 10px;
    border-radius: var(--buttons-border-radius)
}

input:disabled,
select:disabled {
    background-color: #f5f5f5;
    cursor: not-allowed;
}

.field.required label:after {
    content: '*';
    color: #F0435A;
}

label.font-medium {
    font-weight: 900;
}

.hidden-field {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    opacity: 0;
    z-index: 0;
    pointer-events: none;
}

form:not(.advanced) .field.advanced {
    display: none;
}

.toggle-link {
    display: inline-block;
    margin-top: 10px;
    cursor: pointer;
    color: #0077cc;
    text-decoration: underline;
}

#toggle-advanced:checked ~ .field.advanced,
#toggle-advanced:checked ~ .form-actions {
    display: block;
}

.array-field td {
    padding: 0 0.75rem;
    border: none;
    border-bottom: 1px solid #ddd;
}

.array-field td:first-child {
    padding-left: 0;
}

.array-field td:last-child {
    padding-right: 0;
}

/* Inputs inside array rows render with their default chrome at all
   times — previously they were stripped of background/shadow/border
   when not :hover or :focus, which made them look like static text
   and required users to hover the cell before the editable field
   was visible. The standard input styling (set on the element by
   inputs/input.blade.php) does the right thing on its own. */

table .field,
table .static-field {
    padding: 0px;
}

table tr:nth-child(n+2) .field label, 
table tr:nth-child(n+2) .static-field label {
    display: none;
}

/* Buttons */
button {
    border-radius: var(--buttons-border-radius) !important;
}

.link-button {
    background-color: var(--button-primary-bg);
    color: var(--button-primary-fg);
    border-radius: var(--buttons-border-radius) !important;
}

.uppy-StatusBar-actionBtn {
    background-color: var(--brand-primary-colour) !important;
}

/* File Uploader */
.error-status {
    color: red;
    font-weight: 900;
}

.dragover .file-area {
    background-color: #c0c0c0;
}

.toolbar-item {
    border-right: 1px solid rgb(209 213 219);
    padding: 0.5rem;
}

.uppy-Dashboard-Item-preview img.uppy-Dashboard-Item-previewImg,
.file-area .file-preview {
    border-radius: 3px;
    height: 100%;
    object-fit: contain;
    transform: translateZ(0);
    width: 100%;
    border: 1px solid #e5e7eb;
}

.uppy-Dashboard-Item-preview img.uppy-Dashboard-Item-previewImg {
    min-height: 100%;
}

.uppy-StatusBar-actions {
    justify-content: end;
}

.fileItem[data-state="active"] .file-delete {
    display: inline-block;
}

.fileItem[data-state="deleted"] .file-restore {
    display: inline-block;
}

.fileItem[data-state="deleted"] .file-thumb {
    opacity: 0.1;
}

.file-delete {
    right: -8px;
    top: -8px;
    position: absolute; 
}

.file-restore {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    z-index: 2;
}

.file-status {
    font-weight: 900;
}

.restriction-error {
    position: fixed;
    top: -4rem;
    background-color: #F0435A;
    width: 100%;
    padding: 1rem;
    border-radius: 6px;
    font-weight: 900;
    font-size: smaller;
}

/* Icons */
.icon {
    width: 24px;
    height: 24px;
    margin-right: 10px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    color: var(--brand-primary-colour);
}

/* Tasks */
.task-list {
    display: flex;
    flex-direction: column;
}

.task-item {
    display: flex;
    align-items: center;
    padding: 10px 15px;
    border-top: 1px solid #ddd;
    background-color: white;
}

.task-item.overdue {
    color: #721c24;
    background-color: #f8d7da;
}

.task-item.locked {
    background-color: #D0CCD555;
}

.task-item.complete .task-icon {
    color: #1ACBB6;
}

.task-item.incomplete .task-icon {
    color: #D0CCD5;
}

.task-item.locked .task-icon {
    color: #D0CCD5;
}

.icon.task-icon {
    margin-right: 0px;
}

.overdue .icon {
    color: #721c24;
}

.task-content .task-title {
    font-size: 16px;
    font-weight: 400;
    margin: 0;
    line-height: 1.2;
}

.task-content .task-title strong {
    font-weight: bold;
}

.task-content .task-due,
.task-content .task-received {
    font-size: 14px;
    color: #555;
    margin: 5px 0 0;
}

.task-content .task-title {
    font-size: 16px;
    font-weight: 400;
    margin: 0;
    line-height: 1.2;
}
  
.task-content .task-title strong {
    font-weight: bold;
}
  
.task-content .task-due,
.task-content .task-received {
    font-size: 14px;
    color: #555;
    margin: 5px 0 0;
}

/* Notices */
.alert-success {
    color: #155724;
    background-color: #d4edda;
    border: 1px solid #155724;
    padding: 12px 16px;
    border-radius: 12px;
    font-size: 1rem;
    margin: 2rem;
    margin-top: 0;
}

.alert-error {
    color: #721c24;
    background-color: #f8d7da;
    border: 1px solid #721c24;
    padding: 12px 16px;
    border-radius: 12px;
    font-size: 1rem;
    margin: 2rem;
    margin-top: 0;
}

.alert-warning {
    color: #856404;
    background-color: #fff3cd;
    border: 1px solid #856404;
    padding: 12px 16px;
    border-radius: 12px;
    font-size: 1rem;
    margin: 2rem;
    margin-top: 0;
}

/* Passwords */
.password-wrapper {
    display: flex;
    width: 100%;
}

.password-field {
    flex: 1;
    padding: 10px 12px;
    border: 1px solid #ccc;
    border-radius: 6px 0 0 6px;
    font-size: 1rem;
}

.toggle-password {
    padding: 0 12px;
    background-color: #f1f1f1;
    border: 1px solid #ccc;
    border-left: none;
    border-radius: 0 6px 6px 0 !important;
    cursor: pointer;
    font-size: 1rem;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #555;
    transition: background 0.2s;
}

.toggle-password:hover {
    background-color: #e2e2e2;
}

/* API */
#progress-bar {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 4px;
    background-color: var(--brand-primary-colour);
    transition: width 0.5s ease;
    opacity: 0;
    z-index: 1500;
}

/* Dropdowns */
.dropdown {
    position: relative;
    display: inline-flex;
}

.dropdown a {
    position: relative;
    display: inline-flex;
}

.dropdown-toggle {
    border: none;
    cursor: pointer;
}

.dropdown-split .dropdown-toggle {
    border-top-left-radius: 0px !important;
    border-bottom-left-radius: 0px !important;
    padding-left: 0.5rem;
}

.dropdown-split a {
    border-top-right-radius: 0px !important;
    border-bottom-right-radius: 0px !important;
    border-right: 1px solid white;
    padding-right: 0.5rem;
}
.dropdown-menu {
    display: none;
    position: absolute;
    background-color: #f1f1f1;
    min-width: 160px;
    box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
    z-index: 1;
    top: 40px;
}

.dropdown-menu a {
    color: black;
    padding: 12px 16px;
    text-decoration: none;
    display: block;
}

.dropdown-menu a:hover {
    background-color: #ddd;
}

.dropdown.show .dropdown-menu {
    display: block;
}

/* Dialog */
dialog {
    border-radius: 16px;
    max-height: 75vh;
    min-height: 75vh;
    width: 80vw;
}

dialog::backdrop {
    background: rgba(0, 0, 0, 0.2);
    backdrop-filter: blur(3px);
}

dialog .header {
    z-index: 100;
    position: sticky;
    top: 0px;
    background-color: white;
    border-bottom: 1px solid #ddd;
    padding-top: 1rem;
}

dialog .header h2 {
    margin-bottom: 1rem;
}

dialog nav {
    border-top: 1px solid #ddd;
}

#popup-inner {
    overflow-y: hidden;
    display: flex;
}

dialog .content {
    overflow-y: auto;
}

dialog .widget {
    border: none;
    border-left: 1px solid #ddd;
    /*border-radius: 0; */
}

@media screen and (max-width: 600px) {
    dialog {
        border-bottom-left-radius: 0px;
        border-bottom-right-radius: 0px;
        bottom: 0px;
        top: unset;
        margin: 0px;
        max-height: 80vh;
        min-height: unset;
        min-width: 100vw;
        animation: fadeInUp 0.3s ease-out;
    }   

    dialog nav.bg-white {
        background-color: #f8f8f8;
    }

    dialog .content {
        padding-bottom: 0px;
        padding-top: 1rem;
    }

    dialog .widget {
        border: none;
    }

    dialog #popup-inner {
        padding: 0px;
    }

    dialog::before {
        content: '';
        position: absolute;
        top: 0;
        left: 50%;
        transform: translateX(-50%);
        width: 50px;
        height: 5px;
        background-color: #ccc;
        border-radius: 9999px;
        margin-top: 8px;
        z-index: 150;
    }

    .section-info {
        display: none;
    }
}

@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translateY(30%);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}


/* The page header (hero or in-page variant) sits as a static
   first child of .main-panel now that .main-sections owns the
   scroll. No `position: sticky` needed — header naturally stays
   above the scrollable region because it's structurally above it.

   .page-header (in-page variant, when hero is disabled) inherits
   its background from the page element behind it. */

/* Page hero banner — domain-coloured header strip with sticker icon.
   `position: relative` is essential: the hero's children
   (.page-hero-banner__bg svg, .page-hero-banner__label,
   .page-hero-banner__sticker) all use `position: absolute` and
   anchor against this element. Without it they escape to the next
   positioned ancestor (likely <body>), making the title float
   halfway down the page. */
.page-hero-banner {
    --banner-primary: var(--brand-primary-colour, #691EDA);
    --banner-tint: 8;
    --banner-tint-deep: calc(var(--banner-tint) * 2);
    --banner-bg: color-mix(in srgb, var(--banner-primary) calc(var(--banner-tint) * 1%), white);
    --banner-bg-deep: color-mix(in srgb, var(--banner-primary) calc(var(--banner-tint-deep) * 1%), white);
    --banner-soft: color-mix(in srgb, var(--banner-primary) 45%, white);
    --banner-ink: color-mix(in srgb, var(--banner-primary) 75%, white);
    --banner-ink-deep: var(--banner-primary);

    position: relative;
    min-height: 104px;
    flex-shrink: 0;
    background: var(--banner-bg);
    border-bottom: 1px solid #ececec;
    /* No `overflow: hidden` here — it clips the action-dropdown menu
       that opens DOWNWARD past the banner's bottom edge. The
       background ink/SVG that NEEDS clipping is in `__bg` below;
       clipping is scoped there so decorative shapes still stay
       inside the banner while interactive popovers (dropdowns,
       tooltips) can escape. */
}

.page-hero-banner__bg {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 104px;
    pointer-events: none;
    /* Clip the decorative shapes here, not on the parent banner.
       See `.page-hero-banner` above. */
    overflow: hidden;
}

.page-hero-banner__label {
    position: absolute;
    left: 2rem;
    top: 0;
    bottom: 0;
    z-index: 2;
    display: flex;
    align-items: center;
    gap: 16px;
    min-width: 0;
    /* Decorative container — text + image only. The previous
       `right: 240px` was clipping the label to make room for the
       actions/sticker zone, but absolute positioning + an empty
       box was still catching pointer events over the action
       buttons, blocking clicks. Drop the right constraint and
       make the box itself click-through; any interactive child
       inside the label can opt back in with pointer-events: auto. */
    pointer-events: none;
}

/* When an image is present, bottom-align the image and text together
   so their bottom edges share a baseline. The padding keeps the text
   off the banner's bottom edge. */
.page-hero-banner__label--with-image {
    align-items: flex-end;
    padding-bottom: 12px;
}

.page-hero-banner__crumb {
    font-size: 10px;
    letter-spacing: 1.6px;
    font-weight: 700;
    text-transform: uppercase;
    color: var(--banner-ink-deep);
    opacity: 0.75;
}

.page-hero-banner__sticker {
    position: absolute;
    right: 40px;
    top: 50%;
    transform: translateY(-50%) rotate(-4deg);
    z-index: 2;
    width: 62px;
    height: 62px;
    border-radius: 12px;
    background: #fff;
    border: 1.5px solid rgba(0, 0, 0, 0.08);
    box-shadow:
        0 2px 0 rgba(0, 0, 0, 0.06),
        0 4px 10px rgba(0, 0, 0, 0.05);
    display: flex;
    align-items: center;
    justify-content: center;
}

/* When actions sit alongside the domain icon, the sticker grows
   wider into a horizontal pill. Drop the tilt so action buttons
   stay readable, and let width expand to fit the buttons. */
.page-hero-banner__sticker--with-actions {
    width: auto;
    height: auto;
    min-height: 62px;
    transform: translateY(-50%);
    padding: 8px 12px;
    gap: 12px;
}

.page-hero-banner__sticker-icon {
    width: 32px !important;
    height: 32px !important;
    color: var(--banner-primary, var(--brand-primary-colour, #691EDA)) !important;
    stroke: var(--banner-primary, var(--brand-primary-colour, #691EDA)) !important;
    flex-shrink: 0;
}

.page-hero-banner__sticker-actions {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

/* Page actions are mostly navigation (drill-down links, related
   pages), not change-state CTAs — so they use a neutral white/gray
   secondary style rather than the brand CTA colour. Override the
   default .link-button brand background and text colour. */
.page-action.link-button {
    background-color: #fff;
    color: #374151;
    border: 1px solid #d1d5db;
    cursor: pointer;
}

.page-action.link-button:hover {
    background-color: #f9fafb;
    border-color: #9ca3af;
}

.page-action.link-button:focus,
.page-action.link-button:active {
    background-color: #f3f4f6;
}

/* Split-button dropdown caret inside .page-actions — sibling of the
   white .page-action <a>, but rendered as a <button> via <x-button>
   which defaults to `bg-gray-800`. The `button.bg-gray-800` rule
   above remaps that to var(--button-primary-bg) (the brand CTA
   colour), making the caret cyan while the action body next to it
   is white. Override here so the caret matches the action body:
   white background, grey text, same border. */
.page-actions .dropdown-toggle {
    background-color: #fff !important;
    color: #374151 !important;
    border: 1px solid #d1d5db !important;
}

.page-actions .dropdown-toggle:hover {
    background-color: #f9fafb !important;
    border-color: #9ca3af !important;
}

.page-actions .dropdown-toggle:focus,
.page-actions .dropdown-toggle:active {
    background-color: #f3f4f6 !important;
}

/* The split <a> next to the caret carries a `border-right: 1px solid
   white` to visually separate the two halves when both are dark/CTA.
   With the caret now also white, that white border disappears against
   the white background — swap to the same grey we use on the borders
   above so the divider stays visible. */
.page-actions .dropdown-split a {
    border-right-color: #d1d5db;
}

/* The mobile FAB overlay is purely a small-screen affordance — at
   desktop sizes it serves no purpose but still occupies a flex slot
   inside .page-actions, adding a phantom gap. Hide it by default;
   the mobile media query re-enables it when the toggle is checked. */
.page-fab-overlay {
    display: none;
}

/* When a header image is present, bottom-align the image and text
   together so their baselines match. Desktop-only — on mobile the
   page-header switches to flex-direction: column-reverse, and using
   align-items:flex-end there would right-align children instead of
   bottom-aligning them. */
@media screen and (min-width: 601px) {
    .page-header--with-image {
        align-items: flex-end;
    }
}

/* Shared header content styling — used by both the in-page header
   row and the hero banner's __label, so the two render identical
   content at identical sizes. The hero only adds background tint,
   sticker, and the small __crumb line above the title. */
.page-header__image {
    flex-shrink: 0;
    width: 72px;
    height: 72px;
    border-radius: 12px;
    object-fit: cover;
    background: #fff;
    border: 1.5px solid rgba(0, 0, 0, 0.08);
    box-shadow:
        0 2px 0 rgba(0, 0, 0, 0.06),
        0 4px 10px rgba(0, 0, 0, 0.05);
}

.page-header__text {
    display: flex;
    flex-direction: column;
    gap: 4px;
    min-width: 0;
}

.page-header__title-row {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
    min-width: 0;
}

.page-header__title {
    margin: 0;
    font-size: 1.5rem;
    font-weight: 700;
    letter-spacing: -0.2px;
    color: #1a1a1a;
    line-height: 1.2;
    min-width: 0;
}

.page-header__pill {
    display: inline-flex;
    align-items: center;
    padding: 2px 10px;
    border-radius: 9999px;
    font-size: 12px;
    font-weight: 500;
    line-height: 1.4;
    white-space: nowrap;
}

.page-header__meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px 14px;
    margin-top: 4px;
    font-size: 13px;
    color: #4b5563;
}

.page-header__meta-item {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-width: 0;
}

.page-header__meta-icon {
    width: 14px;
    height: 14px;
    flex-shrink: 0;
    color: #6b7280;
}

.page-header__meta-pill {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 2px 10px;
    border-radius: 9999px;
    font-size: 12px;
    font-weight: 500;
    line-height: 1.4;
    white-space: nowrap;
}

.page-header__meta-dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    flex-shrink: 0;
}

/* Page-header mobile (post-base overrides) — these rules must be
   defined AFTER the desktop .page-header__* rules above so the cascade
   applies them last at small viewports. Otherwise the base rules win
   even when the media query matches. */
@media screen and (max-width: 600px) {
    /* Stack vertically (image, text, actions) in natural DOM order.
       Image keeps its 72px intrinsic width via align-self instead of
       being stretched. Bumped left/right padding gives the content
       more breathing room from the viewport edge on small screens. */
    .page-header {
        flex-direction: column;
        align-items: stretch;
        padding-left: 2.5rem;
        padding-right: 2.5rem;
    }

    .page-header__image {
        align-self: flex-start;
    }

    /* On mobile, force the title to claim the full width of its
       title-row so any inline pills wrap to a new line below it.
       Prevents long titles + pills from pushing off-screen. */
    .page-header__title {
        flex-basis: 100%;
    }

    /* Stack meta items vertically and left-align them so each line
       starts at the same x as the title above. */
    .page-header__meta {
        flex-direction: column;
        align-items: flex-start;
        gap: 6px;
    }

    /* Hero banner mobile layout — desktop uses an absolute-positioned
       __label overlay on top of a fixed-height (104px) decorative
       banner. That layout breaks on phone widths because the wrapped
       title + pills + meta extend taller than 104px and visually
       leak up onto the page-tab nav above (which is itself lifted
       above the header via order: -1).

       On mobile, drop the absolute positioning so the label sits in
       normal flow and the banner grows to contain whatever content
       it holds. Image stacks above the text rather than next to it. */
    .page-hero-banner {
        min-height: 0;
        padding: 1rem 1.5rem;
    }

    /* Keep image + text side-by-side on mobile (don't stack) — just
       drop the absolute positioning so the banner can size to fit.
       The text block (__text) handles its own internal stacking. */
    .page-hero-banner__label,
    .page-hero-banner__label--with-image {
        position: static;
        flex-direction: row;
        align-items: flex-start;
        gap: 0.75rem;
        padding-bottom: 0;
        min-width: 0;
    }

    /* Lock the image to its intrinsic width so the text gets the
       remaining row. min-width: 0 lets the text block shrink and wrap
       instead of pushing the row past the banner edge. */
    .page-hero-banner__label .page-header__image {
        flex-shrink: 0;
    }

    .page-hero-banner__label .page-header__text {
        min-width: 0;
        flex: 1;
    }

    /* Hide the decorative SVG + sticker on mobile — the banner is now
       a content carrier rather than a wide decorative strip, and the
       sticker (positioned with right: 40px, transform: translateY(-50%))
       overlaps the stacked label content. */
    .page-hero-banner__bg,
    .page-hero-banner__sticker {
        display: none;
    }
}