/* =====================================================================
   dashboard_style.css — member dashboard, demo dashboard and their satellite
   pages, restyled to the SAME design language as the homepage (index.php's
   "home-modern" theme): white surfaces, #2563eb blue accents, Inter type,
   soft borders instead of glows.

   Every selector from the previous (dark navy / cyan) stylesheet is kept, so
   no page markup needed to change — only the values differ. The old file is
   preserved as _BACKUP/dashboard_style_20260822.css.

   Palette (mirrors .home-modern in index.php):
     brand   #2563eb   brand-2 #0ea5e9   ink  #0f172a
     muted   #64748b   line    #e2e8f0   bg-alt #f8fafc
   ===================================================================== */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=Poppins:wght@300;400;600;700&display=swap');

:root {
    --brand: #2563eb;
    --brand-2: #0ea5e9;
    --ink: #0f172a;
    --muted: #64748b;
    --line: #e2e8f0;
    --bg-alt: #f8fafc;

    /* Height of the member top bar. The sidebar hangs below it and Prompt
       Assist sizes itself against it, so the number was written out by hand in
       four places and had to be kept in sync by memory. It is one value now.

       12px padding + 60px logo + 12px padding + the 1px bottom border = 85.
       The old hardcoded 120px never matched the bar it described either (that
       one measured 111px), which left a 9px seam under the header. */
    --header-h: 85px;
}

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    font-family: 'Inter', 'Poppins', -apple-system, BlinkMacSystemFont, sans-serif;
    background-color: var(--bg-alt);
    color: var(--ink);
    min-height: 100vh;
    margin: 0;
    padding: 0;
}

/* .container here is purely the layout row that holds the sidebar and the
   content column — it must not paint anything.
   The gallery pages also load style.css (the old public-site sheet), where the
   SAME class name is a decorative dark panel:
       .container { background: linear-gradient(135deg,#2a3b57,#415a77);
                    border: 1px solid #415a77; border-radius: 15px; }
   Two stylesheets sharing one class name; the old one's background survived
   because nothing here declared one, which is the navy box that appeared
   wrapped around the white card. Reset it explicitly. */
.container {
    max-width: calc(100% - 290px);
    margin: 40px 0 40px 290px;
    padding: 0 20px;
    display: flex;
    background: none;
    border: 0;
    border-radius: 0;
    box-shadow: none;
}

.content {
    flex: 1;
    min-width: 0;
    padding: 20px;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
    gap: 20px;
    align-content: start;
}

/* Grid and flex children default to min-width:auto, meaning they refuse to
   shrink below their widest piece of content — one long URL or token then
   pushes the whole card past the screen edge on a phone. Allowing them to
   shrink is what makes the wrapping rules below actually take effect. */
.content > *,
.card > * {
    min-width: 0;
}

/* Nav stays DARK on purpose — same reasoning as the homepage: the white
   LumaQube logo needs a dark ground, and it visually ties both together. */
nav {
    background: linear-gradient(90deg, #0b1220, #1e293b);
    padding: 25px 0;
    box-shadow: 0 4px 20px rgba(15, 23, 42, 0.18);
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
    position: sticky;
    top: 0;
    z-index: 1000;
}

.nav-container {
    max-width: 1200px;
    margin: 0 auto;
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0 20px;
}

.nav-logo img {
    height: 60px;
    width: auto;
}

.nav-menu {
    display: flex;
    list-style: none;
    align-items: center;
}

.nav-menu li {
    margin-left: 25px;
}

.nav-menu a, .logout-button {
    color: #cbd5e1;
    text-decoration: none;
    font-weight: 500;
    text-transform: none;
    transition: color 0.3s ease;
    font-family: inherit;
    background: none;
    border: none;
    padding: 0;
    cursor: pointer;
}

.nav-menu a:hover, .logout-button:hover {
    color: #ffffff;
    display: inline-block;
}

.nav-toggle {
    display: none;
    color: #ffffff;
    font-size: 28px;
    cursor: pointer;
}

/* ---------------------------------------------------------------------
   The dashboard top bar, and ONLY that bar.

   This stylesheet is also loaded by pages that have no sidebar and use the
   public nav instead — login.php, demo_trial.php, demo_confirm.php, the two
   demo_*_password.php pages and creator.php. Those still carry a full menu,
   so centring the logo or shrinking the bar for them would wreck their
   layout. dashboard_header.php tags its own <nav> with .member-nav and
   everything below hangs off that class; the plain rules above are untouched.

   With the language picker moved down to the sidebar the bar holds nothing
   but the logo, so it is centred and no longer needs 120px of height.
   --------------------------------------------------------------------- */
nav.member-nav {
    padding: 12px 0;
}

nav.member-nav .nav-container {
    position: relative;
    justify-content: center;
}

/* Flex, so the logo contributes exactly its 60px. As an inline image it also
   carries line-height descender space, which would push the bar a few pixels
   past --header-h and reopen the seam under the header. */
nav.member-nav .nav-logo {
    display: flex;
    align-items: center;
}

/* Taken out of the flex flow so it cannot pull the logo off centre. */
nav.member-nav .nav-toggle {
    position: absolute;
    right: 20px;
    top: 50%;
    transform: translateY(-50%);
}

/* Cards: white with the homepage's blue top border, resting on soft shadow. */
.card {
    background: #ffffff;
    border: 1px solid var(--line);
    border-top: 4px solid var(--brand);
    border-radius: 16px;
    padding: 20px;
    box-shadow: 0 1px 2px rgba(15, 23, 42, 0.06);
    transition: transform 0.3s ease, box-shadow 0.3s ease;
    height: 100%; /* Ensure cards fill grid cell height */
    display: flex;
    flex-direction: column;
}

/* Make sure card content expands */
.card-body {
    flex: 1;
}

/* Copy to clipboard icon styles */
.license-id-container {
    display: inline-flex;
    align-items: center;
}

.copy-icon {
    opacity: 0.7;
    transition: opacity 0.3s ease, transform 0.2s ease;
}

.copy-icon:hover {
    opacity: 1;
    transform: scale(1.1);
    color: #1d4ed8 !important;
}

.copy-icon:active {
    transform: scale(0.95);
    position: relative;
    overflow: hidden;
}

/* The old theme laid a cyan sheen over every card; on white it would only
   muddy the surface, so the pseudo-element stays but draws nothing. */
.card::before {
    content: '';
    display: none;
}

.card:hover {
    transform: translateY(-4px);
    box-shadow: 0 14px 30px rgba(15, 23, 42, 0.10);
    border-color: #cbd5e1;
    border-top-color: var(--brand);
}

.card.dongle-card {
    margin-top: 10px;
}

.card h2 {
    font-size: 1.8rem;
    font-weight: 800;
    color: var(--ink);
    letter-spacing: -0.02em;
    margin-bottom: 20px;
}

.card h3 {
    font-size: 1.3rem;
    font-weight: 600;
    color: var(--ink);
    margin-bottom: 16px;
}

.card h5 {
    font-size: 20px;
    color: var(--brand);
    font-weight: 700;
    margin-bottom: 15px;
    display: flex;
    align-items: center;
    gap: 10px;
}

.card h6 {
    font-size: 16px;
    color: #334155;
    font-weight: 700;
    margin: 15px 0 10px;
}

/* Body copy inside cards. Every value on this dashboard is regular weight next
   to a bold label, and at 14px regular text reads noticeably lighter than the
   label beside it even at the same colour — so it gets weight 500 and the
   full-strength ink, not the muted grey. Fallbacks are spelled out in var()
   because a missing custom property would silently drop the colour to inherit. */
.card p,
.card li,
.card td,
.card dd,
.card small,
.card span:not([class]) {
    color: var(--ink, #0f172a);
    font-weight: 500;
}

.card p {
    font-size: 14px;
    color: var(--ink, #0f172a);
    margin-bottom: 10px;
}

/* Labels stay the strongest thing in the line. */
.card strong,
.card b,
.card dt {
    color: var(--ink, #0f172a);
    font-weight: 700;
}

/* Bootstrap's utility classes are used on this page but only Bootstrap's JS is
   loaded, never its CSS — so these had NO colour at all and inherited. Defined
   here in shades that clear WCAG AA (4.5:1) on white, unlike Bootstrap's own
   #28a745 (3.1:1) and #ffc107 (1.6:1). */
.text-success { color: #15803d; font-weight: 600; }
.text-warning { color: #b45309; font-weight: 600; }
.text-danger  { color: #b91c1c; font-weight: 600; }
.text-primary { color: #1d4ed8; font-weight: 600; }
.text-muted   { color: #475569; }

.form-group {
    margin-bottom: 15px;
}

.form-group label {
    display: block;
    font-size: 0.9rem;
    font-weight: 600;
    color: var(--ink);
    margin-bottom: 5px;
}

.form-group input,
.form-group select,
.form-group textarea {
    width: 100%;
    max-width: 100%;
    box-sizing: border-box;
    background: #ffffff;
    border: 1px solid #cbd5e1;
    border-radius: 8px;
    padding: 8px;
    color: var(--ink);
    font-size: 1rem;
    font-family: inherit;
    transition: border-color 0.3s ease, box-shadow 0.3s ease;
}

.form-group input:disabled {
    background-color: var(--bg-alt);
    color: var(--muted);
    cursor: not-allowed;
}

.form-group select {
    appearance: none;
    background-image: url('data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2210%22%20height%3D%225%22%20viewBox%3D%220%200%2010%205%22%3E%3Cpath%20fill%3D%22%2364748b%22%20d%3D%22M0%200h10L5%205z%22%2F%3E%3C%2Fsvg%3E');
    background-repeat: no-repeat;
    background-position: right 10px center;
    background-size: 10px 5px;
}

.form-group textarea {
    resize: vertical;
    min-height: 80px;
    height: 150px;
}

.form-group input:focus,
.form-group select:focus,
.form-group textarea:focus {
    border-color: var(--brand);
    box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.18);
    outline: none;
}

.btn {
    background: linear-gradient(135deg, var(--brand), var(--brand-2));
    border: none;
    border-radius: 8px;
    padding: 12px 24px;
    color: #ffffff;
    font-weight: 700;
    cursor: pointer;
    transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.btn:hover {
    transform: translateY(-2px);
    box-shadow: 0 10px 22px rgba(37, 99, 235, 0.30);
}

.btn-submit, .btn-close-ticket {
    background: var(--brand);
    color: #fff;
    padding: 10px 20px;
    border: none;
    border-radius: 8px;
    font-weight: 700;
    cursor: pointer;
    transition: background 0.3s ease, transform 0.3s ease;
    margin-right: 10px;
}

.btn-close-ticket {
    margin-top: 10px;
}

.btn-submit:hover, .btn-close-ticket:hover {
    background: #1d4ed8;
    transform: scale(1.03);
}

.btn-info {
    background: linear-gradient(135deg, var(--brand), var(--brand-2));
    color: #ffffff;
    padding: 8px 15px;
    border: none;
    border-radius: 20px;
    font-weight: 700;
    text-decoration: none;
    transition: box-shadow 0.3s ease, transform 0.3s ease;
    display: inline-flex;
    align-items: center;
    gap: 5px;
    cursor: pointer;
}

.btn-info:hover {
    box-shadow: 0 8px 18px rgba(37, 99, 235, 0.30);
    transform: scale(1.04);
    color: #ffffff;
}

.btn-save {
    background: var(--brand);
    color: #fff;
    padding: 10px 20px;
    border: none;
    border-radius: 8px;
    font-weight: 700;
    cursor: pointer;
    transition: background 0.3s ease, transform 0.3s ease;
    margin-top: 15px;
}

.btn-save:hover {
    background: #1d4ed8;
    transform: scale(1.03);
}

.alert {
    padding: 12px;
    border-radius: 8px;
    margin-bottom: 20px;
    font-size: 0.9rem;
}

.alert-error {
    background: #fdecea;
    border: 1px solid #f5c2c7;
    color: #b02a37;
}

.alert-success {
    background: #e6f4ea;
    border: 1px solid #b7e0c0;
    color: #1e7e34;
}

.message, .error {
    padding: 10px;
    border-radius: 8px;
    margin-bottom: 20px;
}

.message {
    background-color: #28a745;
    color: #fff;
}

.error {
    background-color: #dc3545;
    color: #fff;
    grid-column: 1 / -1;
}

.table-container {
    overflow-x: auto;
    width: 100%;
    font-size: 14px;
}

.table {
    width: 100%;
    border-collapse: collapse;
    background: #ffffff;
    border-radius: 8px;
    overflow: hidden;
    cursor: pointer;
}

.table th, .table td {
    padding: 15px;
    text-align: left;
    border-bottom: 1px solid var(--line);
    color: var(--ink);
}

.table th {
    background: var(--bg-alt);
    color: #52606d;
    font-weight: 700;
    font-size: 12px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.table tr:hover {
    background: var(--bg-alt);
}

.table input[type="text"] {
    width: 100%;
    padding: 5px;
    border: 1px solid #cbd5e1;
    border-radius: 5px;
    background-color: #ffffff;
    color: var(--ink);
    font-family: inherit;
}

.table input[type="text"]:focus {
    outline: none;
    border-color: var(--brand);
    box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.18);
}

.license-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 13px;
}

.license-table th, .license-table td {
    padding: 8px;
    text-align: left;
    border-bottom: 1px solid var(--line);
}

.license-table th {
    background: rgba(37, 99, 235, 0.08);
    color: var(--brand);
}

.license-table td {
    color: var(--ink);
}

.storage-bar {
    background: var(--line);
    border-radius: 5px;
    height: 10px;
    margin: 5px 0;
    overflow: hidden;
}

.storage-bar-fill {
    height: 100%;
    background: linear-gradient(90deg, var(--brand), var(--brand-2));
    transition: width 0.5s ease;
}

.notification-list {
    list-style: none;
    padding: 0;
}

.notification-list li {
    font-size: 14px;
    margin-bottom: 8px;
    display: flex;
    align-items: center;
    gap: 8px;
}

.notification-list .urgent {
    color: #dc3545;
}

.copy-icon {
    cursor: pointer;
    color: var(--brand);
    margin-left: 5px;
    font-size: 14px;
}

.copy-icon:hover {
    color: #1d4ed8;
}

.copy-tooltip {
    display: none;
    position: fixed;
    background-color: #28a745;
    color: #fff;
    padding: 5px 10px;
    border-radius: 3px;
    font-size: 12px;
    z-index: 1000;
    white-space: nowrap;
}

/* Copy button beside an ID (dashboard, cloud subscriptions). Behaviour lives in
   dashboard_copy.js, which also drives the older .copy-icon markup above; both
   confirm by turning green with a check for a moment (.is-done).
   Not named .copy-btn: the gallery's green "copy public URL" button already owns
   that class (further down this file, and in dashboard_gallery.php's script). */
.id-copy {
    flex: none; display: inline-flex; align-items: center; justify-content: center;
    width: 30px; height: 30px; border-radius: 8px; cursor: pointer;
    border: 1px solid #cbd5e1; background: #fff; color: #64748b;
}
.id-copy:hover   { border-color: var(--brand); background: #eff6ff; color: var(--brand); }
.id-copy.is-done { border-color: #16a34a; background: #ecfdf5; color: #16a34a; }
.id-copy--sm     { width: 24px; height: 24px; border-radius: 6px; font-size: 11px; }
/* !important: the .copy-icon markup on My Licenses carries an inline colour. */
.copy-icon.is-done { color: #16a34a !important; opacity: 1; }

/* Cloud status chip under each licence on My Licenses — links the licence to
   its subscription on the Cloud Subscriptions page, or offers to add one. */
.cloud-chip {
    display: flex; width: max-content; max-width: 100%; align-items: center; gap: 5px;
    margin-top: 6px; padding: 2px 9px; border-radius: 999px; border: 1px solid;
    font-size: 11.5px; font-weight: 700; text-decoration: none; white-space: nowrap;
}
.cloud-chip.is-ok      { background: #ecfdf5; border-color: #bbf7d0; color: #15803d; }
.cloud-chip.is-soon    { background: #fffbeb; border-color: #fde68a; color: #b45309; }
.cloud-chip.is-expired { background: #fef2f2; border-color: #fecaca; color: #b91c1c; }
.cloud-chip.is-none    { background: #ffffff; border-color: #cbd5e1; border-style: dashed; color: #1d4ed8; }
.cloud-chip:hover      { filter: brightness(.97); text-decoration: none; }

/* Compact outline button for page actions (gallery pages). .is-sm for table
   rows, .is-danger for deletes; .is-done is the copy confirmation that
   dashboard_copy.js sets. */
.g-btn {
    display: inline-flex; align-items: center; gap: 6px; padding: 5px 11px;
    border: 1px solid #cbd5e1; border-radius: 8px; background: #fff; color: #0f172a;
    font: inherit; font-size: 12.5px; font-weight: 600; line-height: 1.2;
    text-decoration: none; cursor: pointer; white-space: nowrap;
}
.g-btn i { color: #64748b; font-size: 12px; }
.g-btn:hover { border-color: var(--brand); background: #eff6ff; color: #1d4ed8; text-decoration: none; }
.g-btn:hover i { color: var(--brand); }
.g-btn.is-sm { padding: 3px 9px; font-size: 12px; }
.g-btn.is-danger { color: #b91c1c; }
.g-btn.is-danger i { color: #dc2626; }
.g-btn.is-danger:hover { border-color: #dc2626; background: #fef2f2; color: #991b1b; }
.g-btn.is-danger:hover i { color: #dc2626; }
.g-btn.is-done { border-color: #16a34a; background: #ecfdf5; color: #15803d; }
.g-btn.is-done i { color: #16a34a; }

.modal {
    display: none;
    position: fixed;
    z-index: 2000;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    overflow: auto;
    background-color: rgba(15, 23, 42, 0.55);
    justify-content: center;
    align-items: center;
}

.modal-content {
    background: #ffffff;
    margin: 10% auto;
    padding: 25px;
    border: 1px solid var(--line);
    border-top: 4px solid var(--brand);
    border-radius: 14px;
    width: 80%;
    max-width: 600px;
    color: var(--ink);
    position: relative;
    z-index: 2001;
    max-height: 80vh;
    overflow-y: auto;
    box-shadow: 0 24px 60px rgba(15, 23, 42, 0.25);
}

.modal-content h5 {
    font-size: 24px;
    color: var(--brand);
    font-weight: 700;
    margin-bottom: 20px;
}

.modal-content p {
    font-size: 16px;
    color: var(--ink);
    margin-bottom: 15px;
}

.modal-content h6 {
    font-size: 20px;
    color: #334155;
    font-weight: 700;
    margin: 20px 0 10px;
}

.close {
    color: var(--muted);
    float: right;
    font-size: 28px;
    font-weight: bold;
    cursor: pointer;
}

.close:hover,
.close:focus {
    color: var(--ink);
    text-decoration: none;
}

.chat-container {
    max-height: 300px;
    overflow-y: auto;
    margin-bottom: 15px;
}

.message {
    padding: 10px;
    margin-bottom: 10px;
    border-left: 3px solid var(--brand);
    background: var(--bg-alt);
    border-radius: 5px;
}

.message.admin {
    border-left-color: #dc3545;
}

.message .meta {
    font-size: 12px;
    color: var(--muted);
    margin-bottom: 5px;
}

.modal-actions {
    margin-top: 20px;
    text-align: center;
}

.modal-actions .btn-info {
    width: 100%;
    max-width: 200px;
    margin: 0 auto;
}

.share-notification {
    position: fixed;
    bottom: 20px;
    left: 50%;
    transform: translateX(-50%);
    background: #ffffff;
    color: var(--ink);
    padding: 10px 20px;
    border-radius: 8px;
    border: 2px solid var(--brand);
    box-shadow: 0 8px 24px rgba(15, 23, 42, 0.18);
    z-index: 3000;
    display: none;
    font-size: 14px;
    font-weight: 600;
    text-align: center;
}

.share-notification.success {
    border-color: #28a745;
}

.share-notification.error {
    border-color: #dc3545;
    color: #b02a37;
}

/* Dark overlay caption sits on top of a photo, so it keeps its dark ground. */
.gallery-item .image-info {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    background: rgba(15, 23, 42, 0.72);
    color: #f1f5f9;
    padding: 4px 8px;
    font-size: 10px;
    font-weight: 400;
    line-height: 1.2;
    text-align: center;
    border-bottom-left-radius: 8px;
    border-bottom-right-radius: 8px;
    opacity: 0;
    transition: opacity 0.3s;
}

.gallery-item:hover .image-info {
    opacity: 1;
}

.filter-table {
    margin-bottom: 10px;
    padding: 10px;
    background: #ffffff;
    border: 1px solid var(--line);
    border-radius: 10px;
    box-shadow: 0 1px 2px rgba(15, 23, 42, 0.06);
}

.filter-table td {
    padding: 5px;
    vertical-align: middle;
}

.filter-table label {
    color: var(--ink);
    margin-right: 10px;
    font-size: 14px;
    font-weight: 600;
}

.filter-table select, .filter-table input[type="date"] {
    padding: 8px;
    border-radius: 5px;
    border: 1px solid #cbd5e1;
    background: #ffffff;
    color: var(--ink);
    font-size: 14px;
    width: 150px;
}

.filter-table button {
    padding: 8px 20px;
    border: none;
    border-radius: 5px;
    font-size: 14px;
    cursor: pointer;
    transition: background 0.3s ease, transform 0.2s ease;
}

.filter-table #deleteSelectedBtn {
    background: #dc3545;
    color: #fff;
}

.filter-table #deleteSelectedBtn:hover {
    background: #b02a37;
    transform: translateY(-2px);
}

.filter-table #deleteByDateBtn {
    background: #dc3545;
    color: #fff;
}

.filter-table #deleteByDateBtn:hover {
    background: #b02a37;
    transform: translateY(-2px);
}

.gallery-container {
    position: relative;
    max-width: 1200px;
    margin: 0 auto;
}

.gallery-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: 15px;
    padding: 10px;
}

.gallery-item {
    position: relative;
    overflow: hidden;
    border-radius: 8px;
    border: 1px solid var(--line);
    box-shadow: 0 1px 2px rgba(15, 23, 42, 0.06);
    transition: transform 0.3s ease, box-shadow 0.3s ease;
    height: 200px;
    width: 200px;
    background: #ffffff;
}

.gallery-item img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    border-radius: 8px;
    cursor: pointer;
}

.gallery-item:hover {
    transform: scale(1.05);
    box-shadow: 0 10px 24px rgba(15, 23, 42, 0.14);
}

.loading-overlay {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(248, 250, 252, 0.94);
    display: flex;
    justify-content: center;
    align-items: center;
    z-index: 100;
    border-radius: 10px;
}

.loading-overlay span {
    color: var(--ink);
    font-size: 24px;
    font-weight: 600;
    text-align: center;
    animation: pulse 1.5s infinite;
}

@keyframes pulse {
    0% { opacity: 1; }
    50% { opacity: 0.5; }
    100% { opacity: 1; }
}

.image-overlay {
    display: none;
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    background: white;
    padding: 20px;
    border-radius: 10px;
    box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
    z-index: 1000;
    max-width: 90%;
    max-height: 90vh;
    width: 300px;
    overflow-y: auto;
    flex-direction: column;
    align-items: center;
}

.image-overlay .close-btn {
    position: absolute;
    top: 10px;
    right: 10px;
    font-size: 24px;
    font-weight: bold;
    background: #dc3545;
    color: #fff;
    border: none;
    border-radius: 50%;
    width: 32px;
    height: 32px;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: background 0.3s;
}

.image-overlay .close-btn:hover {
    background: #b02a37;
}

.image-overlay .modal-content {
    display: flex;
    flex-direction: column;
    align-items: center;
    width: 100%;
    border: none;
    box-shadow: none;
    margin: 0;
    padding: 0;
}

.image-overlay img {
    max-width: 100%;
    max-height: 90vh;
    width: auto;
    height: auto;
    object-fit: contain;
    margin-bottom: 10px;
    border-radius: 5px;
}

.image-overlay .qr-code {
    margin-top: 0;
    margin-bottom: 15px;
    display: flex;
    justify-content: center;
}

.image-overlay .qr-code div {
    border: 2px solid #ccc;
    border-radius: 5px;
}

.image-overlay .buttons {
    margin-top: 10px;
    display: flex;
    flex-direction: row;
    gap: 10px;
    justify-content: center;
}

.image-overlay .buttons .btn-icon {
    background: var(--brand);
    color: white;
    border: none;
    border-radius: 50%;
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: background 0.3s;
    text-decoration: none;
}

.image-overlay .buttons .btn-icon:hover {
    background: #1d4ed8;
}

.image-overlay .right-column {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 15px;
}

.delete-date-overlay {
    display: none;
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(15, 23, 42, 0.6);
    z-index: 2000;
    justify-content: center;
    align-items: center;
}

.delete-date-modal {
    background: #ffffff;
    padding: 20px;
    border-radius: 12px;
    border: 1px solid var(--line);
    border-top: 4px solid #dc3545;
    box-shadow: 0 24px 60px rgba(15, 23, 42, 0.25);
    width: 90%;
    max-width: 400px;
    position: relative;
}

.delete-date-modal .close-btn {
    position: absolute;
    top: 10px;
    right: 10px;
    background: #dc3545;
    color: #fff;
    border: none;
    border-radius: 50%;
    width: 30px;
    height: 30px;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    font-size: 16px;
    transition: background 0.3s, transform 0.2s;
}

.delete-date-modal .close-btn:hover {
    background: #b02a37;
    transform: scale(1.1);
}

.delete-date-modal h5 {
    color: var(--ink);
    font-size: 20px;
    font-weight: 700;
    text-align: center;
    margin-bottom: 20px;
}

.delete-date-modal form {
    display: flex;
    flex-direction: column;
    gap: 15px;
}

.delete-date-modal label {
    color: var(--ink);
    font-size: 14px;
    font-weight: 600;
}

.delete-date-modal input[type="date"] {
    padding: 8px;
    border-radius: 5px;
    border: 1px solid #cbd5e1;
    background: #ffffff;
    color: var(--ink);
    font-size: 14px;
    width: 100%;
}

.delete-date-modal button[type="submit"] {
    padding: 10px 20px;
    background: #dc3545;
    color: #fff;
    border: none;
    border-radius: 5px;
    font-size: 14px;
    font-weight: 700;
    cursor: pointer;
    transition: background 0.3s, transform 0.2s;
}

.delete-date-modal button[type="submit"]:hover {
    background: #b02a37;
    transform: translateY(-2px);
}

.public-url-card {
    margin-bottom: 20px;
    background: var(--bg-alt);
    border: 1px solid var(--line);
    border-radius: 10px;
    padding: 15px;
    box-shadow: none;
}

.public-url-card h6 {
    color: var(--ink);
    margin-bottom: 10px;
}

.public-url-container {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 10px;
}

.public-url-input {
    flex-grow: 1;
    padding: 8px;
    border: 1px solid #cbd5e1;
    border-radius: 5px;
    background: #ffffff;
    color: var(--ink);
    font-size: 14px;
}

.public-url-input:disabled {
    background: #ffffff;
    color: var(--muted);
}

.public-url-btn {
    padding: 8px 16px;
    border: none;
    border-radius: 5px;
    color: #fff;
    cursor: pointer;
    transition: background 0.3s ease, transform 0.2s ease;
}

.copy-btn {
    background: #28a745;
}

.copy-btn:hover {
    background: #1e7e34;
    transform: translateY(-2px);
}

.open-btn {
    background: linear-gradient(135deg, var(--brand), var(--brand-2));
    color: #ffffff;
}

.open-btn:hover {
    box-shadow: 0 8px 18px rgba(37, 99, 235, 0.30);
    transform: translateY(-2px);
}

@media (min-width: 769px) {
    .content {
        padding: 20px;
    }
    .card {
        padding: 15px;
    }
    .image-overlay {
        width: 700px;
    }
    .image-overlay .modal-content {
        display: grid;
        grid-template-columns: 1fr 1fr;
        gap: 20px;
        align-items: center;
    }
    .image-overlay img {
        max-height: 60vh;
    }
    .image-overlay .right-column {
        align-items: center;
    }
    .image-overlay .buttons {
        flex-direction: row;
        justify-content: center;
    }
}

@media (max-width: 768px) {
    .container {
        margin-left: 0;
        flex-direction: column;
    }
    .content {
        grid-template-columns: 1fr;
        padding: 10px;
    }
    .card {
        padding: 15px;
    }
    .table-container {
        font-size: 14px;
    }
    .table th, .table td {
        padding: 10px;
    }
    .modal-content {
        width: 90%;
        margin: 20% auto;
    }
    .gallery-grid {
        grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    }
    .gallery-item {
        height: 150px;
        width: 150px;
    }
    .gallery-item img {
        height: 100%;
        width: 100%;
        object-fit: contain;
    }
    .filter-table td {
        display: block;
        margin-bottom: 10px;
    }
    .filter-table {
        display: flex;
        flex-wrap: wrap;
        justify-content: space-between;
        gap: 10px;
    }
    .filter-table select, .filter-table input[type="date"], .filter-table button {
        width: 100%;
        box-sizing: border-box;
    }
    .image-overlay {
        width: 90%;
        max-height: 85vh;
        padding: 15px;
    }
    .image-overlay img {
        max-height: 50vh;
        width: auto;
        height: auto;
        object-fit: contain;
    }
    .image-overlay .buttons {
        flex-direction: column;
        gap: 15px;
        width: 100%;
        align-items: center;
    }
    .image-overlay .buttons .btn-icon {
        width: 50px;
        height: 50px;
    }
    .public-url-container {
        flex-direction: column;
        gap: 10px;
    }
    .public-url-input {
        width: 100%;
    }
    .public-url-btn {
        width: 100%;
    }
}

@media (max-width: 600px) {
    .container {
        margin: 20px auto;
        padding: 0 10px;
    }
    .card {
        padding: 16px;
    }
    .card h2 {
        font-size: 1.5rem;
    }
    .card h3 {
        font-size: 1.1rem;
    }
    .form-group input,
    .form-group select,
    .form-group textarea {
        padding: 6px;
    }
}

@media (max-height: 600px) and (orientation: portrait) {
    .image-overlay img {
        max-height: 40vh;
    }
    .image-overlay {
        padding: 10px;
    }
}

@media (orientation: portrait) and (max-width: 768px) {
    .table {
        display: block;
    }
    .table thead {
        display: none;
    }
    .table tbody, .table tr {
        display: block;
    }
    .table tr {
        margin-bottom: 15px;
        border-bottom: 2px solid var(--line);
    }
    .table td {
        display: flex;
        justify-content: space-between;
        align-items: center;
        text-align: right;
        padding: 10px;
        position: relative;
        padding-left: 10px;
        border-bottom: 1px solid var(--line);
    }
    .table td:before {
        content: attr(data-label);
        position: static;
        width: auto;
        font-weight: 700;
        color: var(--brand);
        text-align: left;
        margin-right: auto;
    }
    .table td:last-child {
        border-bottom: none;
    }
    .table input[type="text"] {
        width: 150px;
        box-sizing: border-box;
    }
    .copy-icon {
        display: inline-block;
        margin-left: 5px;
    }
}

/* Sidebar Menu Styles - Moved from dashboard_menu.php */
.sidebar {
    width: 250px;
    height: calc(100vh - var(--header-h));
    background: #ffffff;
    padding: 20px;
    border-right: 1px solid var(--line);
    position: fixed;
    top: var(--header-h); /* Start below header */
    left: 0;
    z-index: 1100; /* Higher than header */
    font-family: inherit;
    transition: left 0.3s ease;
    /* A column so the language picker can sit against the bottom edge
       regardless of how many menu items the account has: a trial gets three,
       an agent gets nine. See .sidebar-foot. */
    display: flex;
    flex-direction: column;
}

.list-group {
    display: flex;
    flex-direction: column;
    gap: 10px;
    /* Takes the slack, and scrolls on its own if the menu outgrows the
       column — the footer below must stay reachable either way. */
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
}

/* Pinned to the bottom of the rail. Language is a set-once preference rather
   than navigation, so it sits apart from the menu instead of competing with
   it. This is the only language picker in the member area now — the top bar
   used to carry a second copy that vanished with .nav-menu below 768px,
   which is why a separate mobile one had to exist at all. */
.sidebar-foot {
    flex: 0 0 auto;
    margin-top: auto;
    padding-top: 14px;
    border-top: 1px solid var(--line);
}

.list-group-item {
    background: #ffffff;
    border: 1px solid var(--line);
    border-radius: 10px;
    padding: 15px;
    color: var(--ink);
    text-decoration: none;
    /* Size and leading pinned here rather than inherited: the gallery pages load
       Bootstrap, whose body line-height of 1.5 made every entry taller on those
       pages than on the rest, so the menu visibly changed size between pages. */
    font-size: 16px;
    line-height: 1.25;
    font-weight: 600;
    transition: transform 0.3s ease, box-shadow 0.3s ease, border-color 0.3s ease;
    display: flex;
    align-items: center;
    gap: 10px;
}

.list-group-item:hover {
    transform: translateY(-2px);
    border-color: var(--brand);
    box-shadow: 0 8px 18px rgba(37, 99, 235, 0.14);
}

.list-group-item.active {
    background: linear-gradient(135deg, var(--brand), var(--brand-2));
    color: #ffffff;
    border-color: var(--brand);
}

.list-group-item i {
    font-size: 18px;
}

/* Submenu under a section entry (Reports). Indented behind a rule so the pages
   read as belonging to the section above them rather than as siblings of it. */
.list-group-sub {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin: -4px 0 0 16px;
    padding-left: 12px;
    border-left: 2px solid var(--line);
}

.list-group-sub .list-group-item {
    padding: 10px 13px;
    font-size: 14px;
    font-weight: 500;
    border-radius: 8px;
}

.list-group-sub .list-group-item i {
    font-size: 14px;
    color: #64748b;
}

/* The parent entry already carries the blue gradient for the whole section, so
   the current page inside it is marked more quietly — two gradients stacked
   would read as two separate selections. */
.list-group-sub .list-group-item.active {
    background: #eff6ff;
    border-color: #bfdbfe;
    color: #1d4ed8;
    font-weight: 600;
}

.list-group-sub .list-group-item.active i {
    color: #1d4ed8;
}

/* -- Sidebar vs Bootstrap -------------------------------------------
   The two gallery pages load Bootstrap for their own widgets, and Bootstrap
   styles .list-group-item as well. This file loads last, so it wins wherever
   the two are equally specific — but Bootstrap has three rules that are MORE
   specific than ours, plus a plain a:hover that beats .list-group-item's colour:

     .list-group-item + .list-group-item { border-top-width: 0 }
     .list-group-item:first-child        { border-top-*-radius: inherit }
     .list-group-item:last-child         { border-bottom-*-radius: inherit }
     a:hover                             { color: #0056b3; text-decoration: underline }

   The result was a menu that lost its top borders and corners and turned blue and
   underlined under the cursor, on those two pages only. Restating our own values
   here, scoped to .sidebar so they outrank Bootstrap without touching anything
   else that happens to use a list group. */
/* Only the properties Bootstrap takes away — restating `border` or
   `border-radius` wholesale from here would sit BELOW .list-group-item.active in
   this file and quietly strip the current page's brand-coloured edge. */
.sidebar .list-group-item + .list-group-item {
    border-top-width: 1px;
}

.sidebar .list-group-item:first-child,
.sidebar .list-group-item:last-child {
    border-radius: 10px;
}

.sidebar .list-group-sub .list-group-item:first-child,
.sidebar .list-group-sub .list-group-item:last-child {
    border-radius: 8px;
}

/* Hover changes the card, never the wording: our own :hover sets no colour, so
   without this Bootstrap's a:hover is the only rule left holding one. */
.sidebar .list-group-item:hover,
.sidebar .list-group-item:focus {
    color: var(--ink);
    text-decoration: none;
}

.sidebar .list-group-item.active:hover,
.sidebar .list-group-item.active:focus {
    color: #ffffff;
}

.sidebar .list-group-sub .list-group-item.active:hover,
.sidebar .list-group-sub .list-group-item.active:focus {
    color: #1d4ed8;
}

.sidebar-overlay {
    display: none;
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(15, 23, 42, 0.45);
    z-index: 1090; /* Below sidebar (1100) but above content */
    backdrop-filter: blur(3px);
}

/* Mobile Responsiveness */
@media (max-width: 768px) {
    .container {
        margin-left: 0;
        max-width: 100%;
        padding: 0 10px;
    }

    .sidebar {
        width: 260px;
        height: 100vh;
        top: 0;
        left: -270px; /* Hide off-screen */
        z-index: 1200;
        box-shadow: 2px 0 16px rgba(15, 23, 42, 0.18);
        /* NOT display:block, which it used to be: that would flatten the
           column and unpin the language picker at the bottom. */
        display: flex;
    }

    .sidebar.active {
        left: 0;
    }

    .sidebar-overlay.active {
        display: block;
    }

    .nav-toggle {
        display: flex;
        align-items: center;
        justify-content: center;
        font-size: 20px;
        color: #fff;
        cursor: pointer;
        z-index: 1101;
        background: linear-gradient(135deg, var(--brand), var(--brand-2));
        width: 40px;
        height: 40px;
        border-radius: 8px;
        box-shadow: 0 4px 10px rgba(37, 99, 235, 0.3);
        border: 1px solid rgba(255, 255, 255, 0.2);
    }

    .nav-menu {
        display: none;
    }
}

/* Pemilih bahasa yang lama ada di sini sudah dihapus:
     .nav-lang-slot  — kapsul di top bar, tidak dipakai lagi.
     .sidebar-lang   — salinan khusus mobile, yang hanya ada karena kapsul
                       top bar ikut hilang bersama .nav-menu di ≤768px.
   Sekarang cuma ada satu pemilih, menempel di dasar sidebar (.sidebar-foot
   di atas) dan tampil sama di semua lebar layar. Gaya kontrolnya sendiri
   berada di lang_switcher.php.

   Daftar menu yang bisa di-scroll kini urusan .list-group, bukan .sidebar,
   supaya baris bahasa di dasar tidak ikut ter-scroll. */
@media (max-width: 768px) {
    .list-group {
        -webkit-overflow-scrolling: touch;
    }
}

/* ==================================================================
   Penyeimbangan visual dashboard (2026-08-23)

   Masalah sebelumnya: sembilan kartu diperlakukan identik — border-top
   biru 4px, judul biru 20px, dan tombol biru solid di semuanya. Kalau
   semua menonjol, tidak ada yang menonjol. Aturan di bawah memakai
   warna hanya untuk menunjuk (aksi utama & status), sementara struktur
   dibawa oleh ukuran dan jarak.
   Blok ini sengaja ditaruh paling akhir supaya menimpa aturan di atas
   tanpa perlu mengubahnya — gampang dicabut kalau tidak cocok.
   ================================================================== */

/* -- Lebar & kolom -------------------------------------------------
   auto-fit minmax(350px) di monitor lebar menghasilkan empat kolom
   kurus sampai mepet tepi layar. Membatasi kolom konten membuat grid
   berhenti di tiga kolom dengan sendirinya. */
.content {
    max-width: 1280px;
    /* Tinggi kartu mengikuti isinya, tidak diregangkan mengikuti
       kartu tertinggi di barisnya. */
    align-items: start;
}

.card { height: auto; }

/* -- Aksen kartu ---------------------------------------------------
   Garis biru tebal hanya untuk kartu prioritas; sisanya garis tipis
   biasa seperti sisi kartu yang lain. */
.card { border-top: 1px solid var(--line); }
.card.card--accent   { border-top: 4px solid var(--brand); }
.card.card--success  { border-top: 4px solid #16a34a; }

/* -- Judul kartu ---------------------------------------------------
   Judul kembali ke warna teks biasa. Ikon diturunkan jadi abu-abu:
   fungsinya penanda cepat, bukan penarik perhatian. */
.card h5 {
    font-size: 17px;
    color: var(--ink);
    font-weight: 700;
    letter-spacing: -0.01em;
    margin-bottom: 14px;
}
.card h5 i { color: #94a3b8; font-size: 15px; }
.card.card--accent  h5 i { color: var(--brand); }
.card.card--success h5 i { color: #16a34a; }

/* Hover dibuat lebih tenang — enam kartu yang melompat 4px terasa
   gelisah saat kursor menyapu halaman. */
.card:hover { transform: translateY(-2px); box-shadow: 0 10px 22px rgba(15, 23, 42, 0.08); }

/* -- Tombol sekunder -----------------------------------------------
   Satu tombol solid per kartu. Aksi pendamping memakai versi garis:
   tetap jelas terbaca sebagai tombol, tanpa ikut berteriak. */
.btn-ghost {
    background: #ffffff;
    color: #1d4ed8;           /* 5.4:1 di atas putih — lolos AA */
    border: 1px solid #cbd5e1;
    padding: 8px 15px;
    border-radius: 20px;
    font-weight: 700;
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    cursor: pointer;
    font-family: inherit;
    font-size: inherit;
    line-height: 1.35;
    transition: border-color 0.2s ease, background 0.2s ease;
}
.btn-ghost:hover { border-color: var(--brand); background: #eff6ff; color: #1d4ed8; }
.btn-ghost i { color: #64748b; }
.btn-ghost:hover i { color: var(--brand); }

/* Varian WhatsApp: hijau sebagai identitas kanal, bukan sebagai blok. */
.btn-ghost.is-wa { color: #0f7b41; }        /* 4.9:1 di atas putih */
.btn-ghost.is-wa i { color: #16a34a; }
.btn-ghost.is-wa:hover { border-color: #16a34a; background: #ecfdf5; color: #0f7b41; }

/* Tombol yang berbaris vertikal di dalam kartu. */
.btn-stack { display: flex; flex-direction: column; gap: 8px; }
.btn-stack > a { justify-content: flex-start; }

/* Baris tombol di kaki kartu. */
.card-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 14px; }

/* -- Kepala halaman ------------------------------------------------
   Sapaan dan detail akun dulunya sebuah kartu, sejajar dengan kartu
   berisi data. Sebagai judul halaman ia memberi titik masuk yang
   jelas dan mengosongkan satu sel grid. */
.page-head { grid-column: 1 / -1; margin-bottom: -4px; }
.page-head h1 {
    font-size: 1.55rem;
    font-weight: 800;
    color: var(--ink);
    letter-spacing: -0.02em;
    margin: 0 0 6px;
}
.page-head .sub { font-size: 14px; color: #475569; margin: 0 0 10px; }
.page-head .meta {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 20px;
    font-size: 13px;
    color: #475569;
}
.page-head .meta span { white-space: nowrap; }
.page-head .meta b { color: var(--ink); font-weight: 600; }

/* -- Baris ringkasan angka ----------------------------------------
   Angka-angka kunci tadinya tersebar di empat kartu berbeda. Satu
   baris di atas membuatnya terbaca sekali lihat; kartu di bawah
   tinggal mengurus detail dan aksinya. */
.kpi-strip {
    grid-column: 1 / -1;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 1px;                       /* garis pemisah = latar yang tembus */
    background: var(--line);
    border: 1px solid var(--line);
    border-radius: 14px;
    overflow: hidden;
}
.kpi { background: #ffffff; padding: 14px 16px; min-width: 0; }
.kpi .v {
    font-size: 1.5rem;
    font-weight: 800;
    color: var(--ink);
    line-height: 1.1;
    letter-spacing: -0.02em;
    overflow-wrap: anywhere;
}
.kpi .l {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: #64748b;
    font-weight: 700;
    margin-top: 5px;
}
.kpi .s { font-size: 11.5px; color: #64748b; margin-top: 3px; }
.kpi .s .ok   { color: #15803d; font-weight: 600; }
.kpi .s .warn { color: #b45309; font-weight: 600; }
.kpi .s .bad  { color: #b91c1c; font-weight: 600; }

@media (max-width: 768px) {
    .kpi-strip { grid-template-columns: 1fr 1fr; }
    .kpi { padding: 12px 13px; }
    .kpi .v { font-size: 1.25rem; }
    .page-head h1 { font-size: 1.3rem; }
}

/* Garis aksen dipindah ke pseudo-element. Sebagai `border-top: 4px` ia
   membentuk trapesium di sudut karena bertemu border samping 1px, dan
   ujungnya terlihat melebar keluar dari lengkung kartu. */
.card.card--accent,
.card.card--success { border-top: 1px solid var(--line); position: relative; overflow: hidden; }
.card.card--accent::before,
.card.card--success::before {
    content: '';
    display: block;
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 3px;
}
.card.card--accent::before  { background: var(--brand); }
.card.card--success::before { background: #16a34a; }

/* Kaki ringkasan tiket: jangan sampai tautannya patah ke baris sendiri. */
.ticket-foot { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 12px; }
.ticket-foot a { white-space: nowrap; }

/* ------------------------------------------------------------------
   Tata letak kolom untuk dashboard utama saja.

   Grid menyusun per-baris, jadi satu kartu pendek di ujung baris
   meninggalkan lubang selebar dua kolom di baris berikutnya. Multi-
   kolom mengisi ke bawah dulu, sehingga kartu yang tingginya
   berbeda-beda tetap rapat. Dipakai lewat kelas terpisah karena
   halaman dashboard lain hanya berisi satu kartu — di sana kolom
   ganda justru akan menyempitkannya jadi sepertiga lebar.
   ------------------------------------------------------------------ */
.content--masonry {
    display: block;
    columns: 3;
    column-gap: 20px;
}
.content--masonry > .card {
    /* Kartu tidak boleh terpotong di antara dua kolom. */
    break-inside: avoid;
    page-break-inside: avoid;
    margin-bottom: 20px;
    /* margin-top:0 mencegah celah ganda di puncak tiap kolom. */
    margin-top: 0;
}
.content--masonry > .page-head,
.content--masonry > .kpi-strip { column-span: all; }
.content--masonry > .kpi-strip { margin-bottom: 20px; }
.content--masonry > .error { column-span: all; }

@media (max-width: 1100px) { .content--masonry { columns: 2; } }
@media (max-width: 768px)  { .content--masonry { columns: 1; } }

/* .page-head memakai margin bawah negatif agar rapat dengan grid; di
   tata letak kolom margin itu membuat baris detail akun tertimpa baris
   KPI, jadi di sini diberi jarak positif. */
.content--masonry > .page-head { margin-bottom: 18px; }

/* Di lebar antara ponsel dan desktop (≈769–1100px) tabel lisensi masih
   memakai bentuk tabel penuh sementara ruangnya sudah berkurang oleh
   sidebar, sehingga kolom terakhir terpotong di tepi kartu. Digulirkan
   di dalam wadahnya sendiri — halaman tetap tidak bergeser. */
.table-container { overflow-x: auto; -webkit-overflow-scrolling: touch; max-width: 100%; }

/* ------------------------------------------------------------------
   Keterbacaan teks pendamping (2026-08-23, revisi)

   #475569/#64748b lolos AA secara angka (7.2:1 dan 4.8:1), tapi pada
   13px berat 400 teksnya tetap terbaca pucat di sebelah nilai yang
   tebal — persis keluhan yang sama seperti pada isi kartu dulu.
   Rasio bukan satu-satunya penentu: ukuran dan berat huruf ikut
   menentukan berapa banyak tinta yang benar-benar sampai ke mata.
   Jadi warnanya digelapkan sekalian beratnya dinaikkan.
   ------------------------------------------------------------------ */
.page-head .sub {
    color: #334155;          /* 10.3:1 di atas #f8fafc */
    font-weight: 500;
    font-size: 14.5px;
}
.page-head .meta {
    color: #334155;
    font-weight: 500;
    font-size: 13.5px;
    gap: 6px 22px;
}
.page-head .meta b { font-weight: 700; }

.kpi .l { color: #475569; }   /* 7.6:1, sudah berat 700 */
.kpi .s {
    color: #475569;
    font-weight: 500;
    font-size: 12px;
}

.ticket-foot {
    color: #334155;
    font-weight: 500;
    font-size: 12.5px;
    margin: 14px 0 0;
    padding-top: 12px;
    border-top: 1px solid var(--line);
}
.ticket-foot b { color: var(--ink); font-weight: 700; }
.ticket-foot a { font-weight: 700; }

/* `.card p` (dua bagian selektor) mengalahkan `.ticket-foot` (satu),
   jadi ukuran kaki tiket tadi ikut ukuran paragraf biasa. Disamakan
   bobot selektornya di sini. */
.card p.ticket-foot { font-size: 12.5px; color: #334155; }

/* Baris KPI diberi latar biru sangat tipis supaya terbaca sebagai satu
   kesatuan ringkasan, bukan deretan kartu putih seperti kartu di
   bawahnya. Warna garis pemisah ikut dinaikkan sedikit agar tetap
   terlihat di atas latar yang tidak lagi putih. */
.kpi-strip {
    background: #dbeafe;          /* warna garis pemisah (terlihat lewat gap) */
    border-color: #cfe0fd;
}
.kpi { background: #f2f7ff; }

/* Nada birunya dinaikkan — versi sebelumnya nyaris tidak terbaca sebagai
   warna di layar terang. */
.kpi-strip { background: #bfd6fb; border-color: #a9c8f9; }
.kpi { background: #e2ecff; }
/* Hijau "aktif" perlu sedikit lebih gelap agar tetap lolos AA di atas
   latar yang kini lebih pekat. */
.kpi .s .ok { color: #14612f; }
