@import '@fontsource/dm-sans/latin-400.css';
@import '@fontsource/dm-sans/latin-500.css';
@import '@fontsource/dm-sans/latin-600.css';
@import '@fontsource/dm-sans/latin-700.css';
@import '@fontsource/manrope/latin-600.css';
@import '@fontsource/manrope/latin-700.css';
@import '@fontsource/manrope/latin-800.css';
@import 'tailwindcss';
@plugin '@tailwindcss/typography';
@plugin '@tailwindcss/forms';

/* Keep every scroll area usable while removing visual scrollbar chrome.
   This applies consistently to the shell, tables, drawers, and modals. */
html,
body,
* {
    scrollbar-width: none;
    -ms-overflow-style: none;
}

*::-webkit-scrollbar {
    display: none;
    width: 0;
    height: 0;
}

@source '../../vendor/laravel/framework/src/Illuminate/Pagination/resources/views/*.blade.php';
@source '../../storage/framework/views/*.php';

@theme {
    --font-sans: 'DM Sans', ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji',
        'Segoe UI Symbol', 'Noto Color Emoji';
    --font-heading: 'Manrope', 'DM Sans', ui-sans-serif, system-ui, sans-serif;
    --app-corner-radius: 6px;
}

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

@keyframes table-loading-slide {
    from { transform: translateX(0); }
    to { transform: translateX(194%); }
}

.app-request-progress {
    position: fixed;
    top: 0;
    left: 0;
    z-index: 10000;
    width: 100%;
    height: 2px;
    overflow: hidden;
    opacity: 0;
    pointer-events: none;
    transition: opacity 120ms ease;
}

.app-request-progress.is-active {
    opacity: 1;
}

.app-request-progress::after {
    display: block;
    width: 32%;
    height: 100%;
    border-radius: 9999px;
    background: #0d9488;
    animation: app-request-slide .85s ease-in-out infinite alternate;
    content: '';
}

@keyframes app-request-slide {
    from { transform: translateX(-15%); }
    to { transform: translateX(228%); }
}

/* Developer documentation: one readable, mobile-first presentation for long
   prose, API contracts, diagrams, and wide schema tables. */
.dev-document {
    width: 100%;
    max-width: 100%;
    overflow: hidden;
}

.dev-document-header {
    display: flex;
    min-width: 0;
    flex-direction: column;
    gap: 1rem;
    border-bottom: 1px solid #e2e8f0;
    padding-bottom: 1.25rem;
    margin-bottom: 1.5rem;
}

.dev-document-header h1 {
    margin-top: .25rem;
    color: #0f172a;
    font-family: var(--font-heading);
    font-size: 1.375rem;
    font-weight: 700;
    line-height: 1.25;
}

.dev-document-header p:last-child {
    margin-top: .35rem;
    max-width: 52rem;
    color: #64748b;
    font-size: .875rem;
}

.dev-document-eyebrow {
    color: #0f766e;
    font-size: .6875rem;
    font-weight: 700;
    letter-spacing: .14em;
    text-transform: uppercase;
}

.dev-document article,
.dev-document-content {
    min-width: 0;
    overflow-wrap: anywhere;
}

.dev-document :is(h1, h2, h3, h4) {
    scroll-margin-top: 6rem;
    text-wrap: balance;
}

.dev-document article > h1 {
    font-size: clamp(1.45rem, 4vw, 1.875rem);
}

.dev-document article > h2 {
    margin-top: 2.25rem;
    font-size: clamp(1.125rem, 3vw, 1.35rem);
}

.dev-document article > h3 {
    font-size: 1rem;
}

.dev-document :is(pre, table) {
    max-width: 100%;
}

.dev-document pre {
    overflow-x: auto;
    overscroll-behavior-inline: contain;
    white-space: pre;
}

.dev-document pre code {
    overflow-wrap: normal;
    word-break: normal;
}

.dev-document table {
    display: block;
    width: 100%;
    overflow-x: auto;
    overscroll-behavior-inline: contain;
    font-size: .8125rem;
}

.dev-document :is(th, td) {
    min-width: 8rem;
    white-space: normal;
    overflow-wrap: anywhere;
    vertical-align: top;
}

.dev-document :is(p, li, td) code {
    white-space: normal;
    overflow-wrap: anywhere;
}

.dev-document .not-prose {
    max-width: 100%;
}

.dev-visual {
    min-width: 0;
    margin-bottom: 2rem;
    border: 1px solid #dbe4e1;
    border-radius: 1rem;
    background: #f8faf9;
    padding: 1rem;
}

.dev-visual-heading {
    display: flex;
    min-width: 0;
    flex-direction: column;
    gap: .5rem;
    margin-bottom: 1rem;
}

.dev-visual-heading h2 {
    margin-top: .2rem;
    color: #0f172a;
    font-family: var(--font-heading);
    font-size: 1rem;
    font-weight: 700;
}

.dev-visual-legend {
    color: #64748b;
    font-size: .75rem;
}

.dev-map-group-label {
    margin-bottom: .5rem;
    color: #64748b;
    font-size: .625rem;
    font-weight: 700;
    letter-spacing: .12em;
    text-transform: uppercase;
}

.dev-map-grid {
    display: grid;
    min-width: 0;
    gap: .625rem;
}

.dev-map-node {
    display: flex;
    min-width: 0;
    flex-direction: column;
    align-items: flex-start;
    gap: .25rem;
    border: 1px solid #dbe4e1;
    border-radius: .75rem;
    background: #fff;
    padding: .8rem;
}

.dev-map-node strong,
.dev-process-step strong,
.dev-resolution-flow strong {
    color: #172033;
    font-size: .8125rem;
    line-height: 1.3;
}

.dev-map-node small,
.dev-process-step small,
.dev-resolution-flow small {
    color: #64748b;
    font-size: .7rem;
    line-height: 1.45;
}

.dev-map-icon,
.dev-map-number {
    display: inline-flex;
    min-width: 1.75rem;
    min-height: 1.5rem;
    align-items: center;
    justify-content: center;
    border-radius: .4rem;
    background: #e6f5f1;
    color: #0f766e;
    font-size: .55rem;
    font-weight: 800;
    letter-spacing: .05em;
}

.dev-map-number {
    border-radius: 999px;
    font-size: .65rem;
}

.dev-map-node-accent {
    border-color: #bcded4;
}

.dev-map-node-ledger {
    border-left: 3px solid #0f766e;
}

.dev-map-connector {
    display: flex;
    height: 1.75rem;
    align-items: center;
    justify-content: center;
}

.dev-map-connector span {
    position: relative;
    width: 1px;
    height: 1.15rem;
    background: #94a3b8;
}

.dev-map-connector span::after {
    position: absolute;
    bottom: -.1rem;
    left: 50%;
    width: .4rem;
    height: .4rem;
    border-right: 1px solid #64748b;
    border-bottom: 1px solid #64748b;
    content: '';
    transform: translateX(-50%) rotate(45deg);
}

.dev-process-flow {
    display: grid;
    min-width: 0;
    gap: .625rem;
}

.dev-process-step {
    position: relative;
    display: grid;
    min-width: 0;
    grid-template-columns: 2rem minmax(0, 1fr);
    column-gap: .625rem;
    border: 1px solid #dbe4e1;
    border-radius: .75rem;
    background: #fff;
    padding: .8rem;
}

.dev-process-step > span {
    grid-row: span 2;
    color: #0f766e;
    font-size: .7rem;
    font-weight: 800;
}

.dev-resolution-flow {
    display: grid;
    min-width: 0;
    gap: .625rem;
    margin-top: 1rem;
    border-top: 1px dashed #cbd5e1;
    padding-top: 1rem;
}

.dev-resolution-start,
.dev-resolution-branch {
    display: flex;
    min-width: 0;
    flex-direction: column;
    gap: .2rem;
    border: 1px solid #dbe4e1;
    border-radius: .75rem;
    background: #fff;
    padding: .8rem;
}

.dev-resolution-branch > span {
    width: fit-content;
    border-radius: 999px;
    padding: .15rem .45rem;
    font-size: .625rem;
    font-weight: 700;
}

.dev-resolution-clean {
    border-color: #a7e4cc;
}

.dev-resolution-clean > span {
    background: #dff8ed;
    color: #047857;
}

.dev-resolution-issue {
    border-color: #f4d28b;
}

.dev-resolution-issue > span {
    background: #fff3d6;
    color: #a15107;
}

.dev-journey-track {
    display: grid;
    min-width: 0;
    gap: .625rem;
}

.dev-journey-step {
    position: relative;
    display: grid;
    min-width: 0;
    grid-template-columns: 2rem minmax(0, 1fr);
    gap: .65rem;
    border: 1px solid #dbe4e1;
    border-radius: .75rem;
    background: #fff;
    padding: .8rem;
}

.dev-journey-step > span {
    display: inline-flex;
    width: 1.75rem;
    height: 1.75rem;
    align-items: center;
    justify-content: center;
    border-radius: 999px;
    background: #e6f5f1;
    color: #0f766e;
    font-size: .625rem;
    font-weight: 800;
}

.dev-journey-step > div {
    display: flex;
    min-width: 0;
    flex-direction: column;
    gap: .2rem;
}

.dev-journey-step strong {
    color: #172033;
    font-size: .8125rem;
}

.dev-journey-step small {
    color: #64748b;
    font-size: .7rem;
    line-height: 1.45;
}

@media (min-width: 640px) {
    .dev-document-header {
        flex-direction: row;
        align-items: center;
        justify-content: space-between;
    }

    .dev-visual {
        padding: 1.25rem;
    }

    .dev-visual-heading {
        flex-direction: row;
        align-items: flex-end;
        justify-content: space-between;
    }

    .dev-map-grid-three {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }

    .dev-map-grid-four {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .dev-process-flow {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .dev-journey-track {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .dev-resolution-flow {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .dev-resolution-start {
        grid-column: 1 / -1;
        text-align: center;
    }
}

@media (min-width: 1024px) {
    .dev-map-grid-four {
        grid-template-columns: repeat(4, minmax(0, 1fr));
    }

    .dev-process-flow {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }

    .dev-journey-track {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}

@media (max-width: 639px) {
    .dev-document .prose {
        font-size: .875rem;
    }

    .dev-document table {
        margin-inline: 0;
    }

    .dev-document pre {
        border-radius: .65rem;
        font-size: .72rem;
        line-height: 1.55;
    }

    .dev-document .not-prose.flex {
        align-items: flex-start;
        flex-wrap: wrap;
    }
}

/* Apins Control adaptation shared by every authenticated role. Navigation
   and permissions stay role-specific; only the visual shell is unified. */
.control-shell-page {
    --app-corner-radius: 16px;
    background: #f5f7f5;
    color: #0b172a;
    font-family: var(--font-sans);
    font-size: 15px;
}

.control-shell-page :is(h1, h2, h3, .section-heading),
.control-shell-page .tabular-nums {
    font-family: var(--font-heading);
    letter-spacing: -.025em;
}

.control-shell-page::before,
.control-shell-page::after {
    display: none;
}

.control-shell-page #app-sidebar {
    width: 16.5rem;
    border-right-color: #1d3048;
    background: #0b172a;
    box-shadow: none;
}

.control-shell-page #app-sidebar > div:first-child {
    border-bottom-color: #1d3048;
}

.control-shell-page #app-sidebar-navigation {
    gap: 1.25rem;
    padding-block: 1.25rem;
}

.control-shell-page #app-sidebar-navigation > div > p {
    color: #68788c;
    font-size: .625rem;
    letter-spacing: .12em;
}

.control-shell-page #app-sidebar-navigation a {
    min-height: 2.55rem;
    border-radius: .65rem;
    padding-block: .6rem;
    color: #c3ceda;
    font-size: .8125rem;
    white-space: nowrap;
}

.control-shell-page #app-sidebar-navigation a:hover {
    background: #14263d;
    color: white;
}

.control-shell-page #app-sidebar-navigation a[aria-current='page'] {
    background: #1a3a4d;
    color: #83e0c7;
    box-shadow: none;
    --tw-ring-color: transparent;
}

.control-shell-page #app-sidebar-navigation a[aria-current='page'] > span:first-child {
    display: none;
}

.control-shell-page #app-topbar {
    border-bottom-color: #e2e8e4;
    background: rgb(255 255 255 / 88%);
    box-shadow: none;
}

.control-shell-page #app-topbar h1 {
    font-family: var(--font-heading);
    font-size: .875rem;
    font-weight: 700;
    letter-spacing: -.02em;
    white-space: nowrap;
}

.control-shell-page .app-topbar-accent {
    display: none;
}

.control-shell-page main[role='main'],
.control-shell-page main {
    --admin-paper: #f5f7f5;
}

.control-shell-page .app-content {
    min-width: 0;
}

.control-shell-page .app-content > * {
    min-width: 0;
}

.control-shell-page .content-stack {
    display: flex;
    min-width: 0;
    flex-direction: column;
    gap: 1rem;
}

.control-shell-page .content-stack > :is(.toolbar, .table-card, .card) {
    margin-block: 0;
}

.control-shell-page .content-stack > :is(.alert-banner, .warning-banner) {
    margin-bottom: 0;
}

/* Margin lama pada pemanggil tidak boleh menggandakan ritme content-stack. */
.control-shell-page .content-stack > .app-notice {
    margin-block: 0;
}

.control-shell-page .card,
.control-shell-page .table-card,
.control-shell-page .toolbar,
.control-shell-page .dashboard-panel {
    border-color: #e2e8e4;
    background: #fff;
    box-shadow: none;
    --tw-ring-color: transparent;
    backdrop-filter: none;
}

.control-shell-page .dashboard-panel {
    border-width: 1px;
    border-style: solid;
    border-radius: var(--app-corner-radius);
}

.control-shell-page .card:hover {
    border-color: #d4ddd7;
}

.control-shell-page .table-card thead {
    background: #f8faf8;
}

.control-shell-page .table-card table {
    min-width: 48rem;
    font-size: 0.75rem;
}

.control-shell-page .table-card {
    max-width: 100%;
    overscroll-behavior-inline: contain;
}

.control-shell-page .table-card :is(th, td) {
    white-space: nowrap;
}

/* Data tables are intentionally denser than cards/forms. Existing utility
   sizes inside cells are normalized as well, so every role gets the same
   compact table typography instead of a mix of 12/14/16px labels. */
.control-shell-page .table-card :is(th, td) :where(
    .text-sm,
    .text-base,
    .text-lg,
    .text-xl,
    .text-2xl
) {
    font-size: 0.75rem;
    line-height: 1rem;
}

.control-shell-page .table-card thead th {
    font-size: 0.6875rem;
    line-height: 0.875rem;
}

/* Modal copy must wrap naturally even though table actions and normal app
   buttons use nowrap. This prevents long labels/messages stretching dialogs
   sideways on phones and narrow desktop windows. */
.control-shell-page :is(.app-modal-panel, .confirm-dialog-panel) {
    min-width: 0;
    overflow-wrap: anywhere;
}

.control-shell-page :is(.app-modal-panel, .confirm-dialog-panel) :is(
    h1,
    h2,
    h3,
    h4,
    p,
    label,
    span,
    button,
    a
) {
    min-width: 0;
    max-width: 100%;
    white-space: normal;
    overflow-wrap: anywhere;
}

.control-shell-page :is(
    .btn-primary,
    .btn-secondary,
    .btn-danger,
    .btn-success,
    .btn-warning,
    .btn-link,
    .btn-link-danger,
    .badge
) {
    flex-shrink: 0;
    white-space: nowrap;
}

.control-shell-page :is(.toolbar, .card) > * {
    min-width: 0;
}

.control-shell-page .toolbar {
    align-items: center;
}

.control-shell-page .toolbar :is(input, select) {
    min-width: 0;
}

.control-shell-page .btn-primary {
    background: #0b172a;
    box-shadow: none;
}

.control-shell-page .btn-primary:hover {
    background: #14243a;
}

.control-shell-page .admin-control-welcome {
    border: 1px solid #d8eae3;
    border-radius: 1.2rem;
    background: rgb(255 255 255 / 78%);
    color: #0b172a;
    box-shadow: none;
    backdrop-filter: blur(8px);
}

.control-shell-page .admin-control-welcome::after {
    display: none;
}

.control-shell-page .dashboard-hero-art {
    display: none;
}

.control-shell-page .admin-control-welcome > div {
    position: relative;
    z-index: 1;
}

.control-shell-page .admin-control-welcome > div > div:last-child {
    border-color: #d8eae3;
    background: rgb(255 255 255 / 68%);
    color: #0b172a;
}

.control-shell-page .admin-control-welcome > div > div:last-child p {
    color: #526171;
}

.control-shell-page .admin-control-welcome > div > div:last-child > div:first-child {
    background: #087565;
    color: white;
}

@media (max-width: 639px) {
    .control-shell-page {
        font-size: 14px;
    }

    .control-shell-page #app-topbar h1 {
        max-width: min(56vw, 18rem);
        overflow: hidden;
        text-overflow: ellipsis;
    }

    .control-shell-page .toolbar {
        align-items: stretch;
    }

    .control-shell-page .toolbar :is(.btn-primary, .btn-secondary) {
        width: 100%;
    }

    .control-shell-page main {
        padding: 1rem;
    }

    .control-shell-page .content-stack {
        gap: .875rem;
    }

    .control-shell-page .app-content .card {
        padding: 1rem;
    }

    .control-shell-page .app-content .toolbar {
        padding: .875rem;
    }

    .control-shell-page .app-content :is(.card, .toolbar, .table-card) {
        border-radius: .875rem;
    }

    .control-shell-page .app-content :is(p, li) {
        line-height: 1.55;
    }

    .control-shell-page .app-content .table-card::after {
        position: sticky;
        right: 0;
        display: block;
        width: 2.5rem;
        height: 0;
        margin-left: auto;
        background: linear-gradient(to right, transparent, rgb(255 255 255 / 80%));
        content: '';
        pointer-events: none;
    }

    .control-shell-page .admin-control-welcome h1 {
        font-size: clamp(1.25rem, 6vw, 1.6rem);
        white-space: nowrap;
    }
}

[x-cloak] {
    display: none !important;
}

/* Scrolling stays fully functional (wheel/trackpad/touch/keyboard) - only
   the visible track/thumb is hidden, for the sidebar nav and main content
   scroll containers where the default OS scrollbar reads as visual clutter
   rather than a useful affordance. */
.no-scrollbar {
    scrollbar-width: none;
    -ms-overflow-style: none;
}
.no-scrollbar::-webkit-scrollbar {
    display: none;
}

/* Scoped to application data tables. Keeping these rules in the components
   layer lets an explicit row utility (for totals, warnings, etc.) override
   the generic zebra/hover treatment. */
@layer components {
    .table-card tbody tr:nth-child(even) {
        background-color: rgba(248, 250, 252, .7);
        background-color: color-mix(in oklab, var(--color-slate-50) 55%, transparent);
    }

    .table-card tbody tr:hover {
        background-color: rgba(240, 253, 250, .82);
        background-color: color-mix(in oklab, var(--color-teal-50) 62%, transparent);
    }

    .table-card table {
        width: 100%;
    }

    .table-card thead {
        background: linear-gradient(180deg, color-mix(in oklab, var(--color-slate-50) 94%, white), color-mix(in oklab, var(--color-slate-100) 72%, white));
    }

    .table-card thead th {
        border-bottom: 1px solid color-mix(in oklab, var(--color-slate-200) 82%, transparent);
        color: var(--color-slate-600);
        font-size: 0.6875rem;
        font-weight: 700;
        letter-spacing: 0.065em;
        line-height: 0.875rem;
    }

    .table-card tbody tr {
        transition: background-color 160ms ease;
    }

    .table-card tbody td {
        border-color: color-mix(in oklab, var(--color-slate-200) 58%, transparent);
    }
}

/* Legacy table markup still uses slate-400 for secondary labels and empty
   messages. Raise it one step inside data tables so small text remains
   readable without changing decorative icons on dark surfaces. */
.table-card .text-slate-400 {
    color: var(--color-slate-500);
}

/* One compact corner system for every rectangular UI element in the
   authenticated app. True circles/pills keep `rounded-full`. */
.app-page [class*='rounded-']:not(.rounded-full),
.app-page .btn-primary,
.app-page .btn-secondary,
.app-page .btn-danger,
.app-page .btn-success,
.app-page .btn-warning,
.app-page .btn-link,
.app-page .btn-link-danger,
.app-page .card,
.app-page .table-card,
.app-page .toolbar,
.app-page .field-input,
.app-page .field-file,
.app-page .field-checkbox {
    border-radius: var(--app-corner-radius);
}

.app-page {
    position: relative;
    isolation: isolate;
}

.app-page::before {
    position: fixed;
    z-index: -1;
    top: 3rem;
    right: -8rem;
    width: 26rem;
    height: 26rem;
    border-radius: 9999px;
    background: color-mix(in oklab, var(--color-teal-100) 40%, transparent);
    filter: blur(90px);
    opacity: .55;
    content: '';
    pointer-events: none;
}

.app-page::after {
    position: fixed;
    z-index: -1;
    bottom: -12rem;
    left: 18%;
    width: 30rem;
    height: 30rem;
    border-radius: 9999px;
    background: color-mix(in oklab, var(--color-sky-100) 35%, transparent);
    filter: blur(100px);
    opacity: .45;
    content: '';
    pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        scroll-behavior: auto !important;
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
    }

    .btn-primary,
    .btn-secondary,
    .btn-danger,
    .btn-success,
    .btn-warning,
    .card {
        transform: none !important;
    }
}

/* Same reasoning as .table-card below, applied to the plain <table> markup
   used throughout the /dev documentation pages (Tentang, Skema Database,
   API Wali/Kiosk, Instalasi) and the PRD - those tables sit directly inside
   a `.prose article`, not a `.table-card` wrapper, so without this they
   overflowed the *whole page* horizontally on a phone (title/nav pushed off
   too) instead of just scrolling the table itself. display:block lets the
   browser give the table its own scroll container while still laying out
   cells normally (no forced single-line/`white-space:nowrap`, since these
   cells hold paragraph-length descriptions meant to keep wrapping). */
.prose table {
    display: block;
    overflow-x: auto;
}

/* Long unbroken strings (route paths like
   /wali/anak/{santri}/tagihan/{tagihan}/topup/core, appearing constantly
   across the /dev docs) have no whitespace for the browser to wrap at by
   default, so an inline `code` span could push past the .prose column's
   width on a narrow phone screen instead of wrapping - this lets it break
   mid-string as a last resort rather than overflow. */
.prose code {
    overflow-wrap: break-word;
}

@layer components {
    .btn-primary {
        @apply inline-flex min-h-10 items-center justify-center gap-2 rounded-xl bg-linear-to-b from-teal-700 to-teal-800 px-4 py-2 text-sm font-semibold text-white shadow-sm ring-1 ring-inset ring-teal-500/20 transition duration-200 hover:-translate-y-px hover:from-teal-800 hover:to-teal-700 hover:shadow-md focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-teal-700 active:translate-y-0 disabled:pointer-events-none disabled:opacity-50;
    }
    .btn-secondary {
        @apply inline-flex min-h-10 items-center justify-center gap-2 rounded-xl border border-slate-200 bg-white/90 px-4 py-2 text-sm font-semibold text-slate-700 shadow-sm transition duration-200 hover:-translate-y-px hover:border-slate-300 hover:bg-white hover:shadow-md focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-teal-600 active:translate-y-0 disabled:pointer-events-none disabled:opacity-50;
    }
    .btn-danger {
        @apply inline-flex min-h-10 items-center justify-center gap-2 rounded-xl bg-linear-to-b from-red-700 to-red-800 px-4 py-2 text-sm font-semibold text-white shadow-sm ring-1 ring-inset ring-red-500/20 transition duration-200 hover:-translate-y-px hover:from-red-600 hover:to-red-700 hover:shadow-md focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-red-700 active:translate-y-0 disabled:pointer-events-none disabled:opacity-50;
    }
    .btn-success {
        @apply inline-flex min-h-10 items-center justify-center gap-2 rounded-xl bg-linear-to-b from-emerald-700 to-emerald-800 px-4 py-2 text-sm font-semibold text-white shadow-sm ring-1 ring-inset ring-emerald-500/20 transition duration-200 hover:-translate-y-px hover:from-emerald-800 hover:to-emerald-700 hover:shadow-md focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-emerald-700 active:translate-y-0 disabled:pointer-events-none disabled:opacity-50;
    }
    .btn-warning {
        @apply inline-flex min-h-10 items-center justify-center gap-2 rounded-xl bg-linear-to-b from-amber-700 to-amber-800 px-4 py-2 text-sm font-semibold text-white shadow-sm ring-1 ring-inset ring-amber-500/20 transition duration-200 hover:-translate-y-px hover:from-amber-800 hover:to-amber-700 hover:shadow-md focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-amber-700 active:translate-y-0 disabled:pointer-events-none disabled:opacity-50;
    }
    .btn-link {
        @apply inline-flex items-center gap-1 rounded-lg px-1.5 py-1 text-xs font-semibold text-teal-700 transition hover:bg-teal-50 hover:text-teal-800;
    }
    .btn-link-danger {
        @apply inline-flex items-center gap-1 rounded-lg px-1.5 py-1 text-xs font-semibold text-red-600 transition hover:bg-red-50 hover:text-red-700;
    }
    .table-action-icon {
        @apply relative inline-flex size-8 shrink-0 items-center justify-center rounded-md border border-transparent bg-slate-50 p-0 text-slate-500 transition-colors hover:border-teal-200 hover:bg-teal-50 hover:text-teal-700 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-teal-600 disabled:cursor-wait disabled:opacity-65;
    }
    .table-action-icon.table-action-danger {
        @apply border-red-100 text-red-600 hover:border-red-200 hover:bg-red-50 hover:text-red-700 focus-visible:outline-red-600;
    }
    .table-action-icon svg {
        @apply size-3.75 pointer-events-none;
    }

    /* Server-rendered fallback for Livewire morphs. The old implementation
       briefly exposed the text label while JavaScript rebuilt the icon after
       closing a modal. These rules make every standard table action icon-only
       from the very first paint; JS then replaces the fallback with the
       action-specific SVG without any text flash. */
    .table-card :is(.btn-link, .btn-link-danger) {
        @apply relative inline-flex size-8 shrink-0 items-center justify-center rounded-md border border-transparent bg-slate-50 p-0 text-slate-500 transition-colors hover:border-teal-200 hover:bg-teal-50 hover:text-teal-700;
        font-size: 0;
        line-height: 0;
    }
    .table-card .btn-link-danger {
        @apply border-red-100 text-red-600 hover:border-red-200 hover:bg-red-50 hover:text-red-700;
    }
    .table-card :is(.btn-link, .btn-link-danger):not([data-action-icon])::before {
        width: .9375rem;
        height: .9375rem;
        background-color: currentColor;
        content: '';
        /* Neutral action icon shown only during the very short Livewire
           server-DOM phase before the specific icon mapping runs. */
        mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Ccircle cx='5' cy='12' r='1.75'/%3E%3Ccircle cx='12' cy='12' r='1.75'/%3E%3Ccircle cx='19' cy='12' r='1.75'/%3E%3C/svg%3E") center / contain no-repeat;
    }
    .table-action-icon[data-action-loading='true'] svg {
        animation: table-action-spin .7s linear infinite;
    }
    .table-card.table-is-loading {
        position: relative;
    }
    .table-card.table-is-loading::before {
        position: sticky;
        top: 0;
        left: 0;
        z-index: 20;
        display: block;
        width: 34%;
        height: 2px;
        margin-bottom: -2px;
        border-radius: 9999px;
        background: var(--color-teal-600);
        animation: table-loading-slide 1s ease-in-out infinite alternate;
        content: '';
    }
    .card {
        @apply border border-white/80 bg-white/90 p-6 shadow-sm ring-1 ring-slate-200/60 backdrop-blur-sm;
        border-radius: var(--app-corner-radius);
    }
    .table-card {
        /* overflow-x-auto (not overflow-hidden) so a table wider than the
           viewport - true for nearly every admin table on a phone - can be
           scrolled to reach its off-screen columns, instead of just getting
           silently clipped with no way to see the rest. Still clips to the
           rounded corners exactly like overflow-hidden did. */
        @apply overflow-x-auto border border-white/80 bg-white/90 shadow-sm ring-1 ring-slate-200/60 backdrop-blur-sm;
        border-radius: var(--app-corner-radius);
    }
    .field-input {
        @apply block min-h-10 w-full rounded-xl border-slate-200 bg-slate-50/80 px-3.5 py-2.5 text-sm text-slate-900 shadow-xs transition duration-200 placeholder:text-slate-500 hover:border-slate-300 hover:bg-white focus:border-teal-600 focus:bg-white focus:outline-none focus:ring-4 focus:ring-teal-600/10 disabled:cursor-not-allowed disabled:bg-slate-100 disabled:text-slate-500;
    }
    .badge {
        @apply inline-flex items-center gap-1 rounded-full px-2.5 py-1 text-[11px] font-semibold ring-1 ring-inset ring-current/10;
    }
    .field-file {
        @apply block w-full rounded-xl border border-dashed border-slate-300 bg-slate-50/80 p-2 text-sm text-slate-600 transition hover:border-teal-300 hover:bg-teal-50/40 file:mr-4 file:rounded-lg file:border-0 file:bg-teal-100 file:px-4 file:py-2.5 file:text-sm file:font-semibold file:text-teal-800 file:transition hover:file:bg-teal-200;
    }
    .field-checkbox {
        @apply h-4.5 w-4.5 rounded-md border-slate-300 text-teal-600 shadow-sm focus:ring-4 focus:ring-teal-600/10 focus:ring-offset-0;
    }
    .field-radio {
        @apply h-4.5 w-4.5 border-slate-300 text-teal-600 shadow-sm focus:ring-4 focus:ring-teal-600/10 focus:ring-offset-0;
    }
    .section-heading {
        @apply text-base font-semibold tracking-tight text-slate-900;
    }
    .section-description {
        @apply mt-1 text-sm leading-relaxed text-slate-600;
    }
    .toolbar {
        @apply flex flex-col gap-3 border border-white/90 bg-white/90 p-4 shadow-sm ring-1 ring-slate-200/60 backdrop-blur-sm sm:flex-row sm:flex-wrap sm:items-center;
        border-radius: var(--app-corner-radius);
    }
}
