:root {
  /* ------------------------------------------------------------------ colour
     One place for every colour in the application. Page stylesheets use these
     tokens and never literal values - that is what makes a white-label
     rebrand a single-file change, and it is why the same grey no longer
     appears as four slightly different hex codes.

     Every text token reaches at least 4.5:1 (WCAG AA) against both white
     cards and the page background; the state colours reach it against their
     own tinted background as well. The previous palette did not: #94a3b8 as
     text managed 2.6:1, the green 2.5:1, the amber 2.2:1. That is what made
     the interface look washed out. */

  /* -- brand ------------------------------------------------------------- */
  --primary:        #1a1c20;
  --primary-hover:  #2d3748;
  --accent:         #c42a76;   /* 5.3:1 on white (was #d63384, 4.5:1) */
  --accent-strong:  #a52260;
  --accent-light:   #fce7f0;

  /* -- surfaces ---------------------------------------------------------- */
  --bg-body:        #eef1f5;
  --bg-card:        #ffffff;
  --bg-subtle:      #f5f7fa;   /* striped rows, toolbars   */
  --bg-muted:       #eceff4;   /* section headers, chips   */

  /* -- text -------------------------------------------------------------- */
  --text-main:      #14181f;   /* 17.8:1 */
  --text-strong:    #263041;   /* 13.3:1  headings on cards */
  --text-muted:     #4a5568;   /*  7.5:1  secondary text    */
  --text-faint:     #5f6a78;   /*  5.5:1  hints, meta - was #94a3b8 at 2.6:1 */
  --text-on-dark:   #ffffff;
  /* What is legible on top of a state colour. White here, near-black in the
     dark set - the dark greens and ambers are light colours, and white text
     on them is the classic dark-theme button nobody can read. */
  --text-on-state:  #ffffff;

  /* -- lines ------------------------------------------------------------- */
  --border:         #dbe1e9;
  --border-strong:  #c2cbd8;
  --border-focus:   #2563eb;

  /* -- states ------------------------------------------------------------ */
  --success:        #10794f;  --success-bg: #e9f7f0;
  --danger:         #c62828;  --danger-bg:  #fdeaea;
  --warning:        #a35a06;  --warning-bg: #fdf3e3;
  --info:           #1d63b8;  --info-bg:    #e8f0fb;

  /* The line around a tinted chip. Neither the tint nor the text colour: a
     chip bordered in its own full-strength colour shouts, and one bordered in
     --border disappears against the tint. Written down because the same four
     pills are drawn on a dozen pages and were a dozen slightly different
     yellows. */
  --success-line:   #a7dcc2;
  --danger-line:    #f3b8b8;
  --warning-line:   #e8cf9a;
  --info-line:      #b9cff0;

  /* A fifth hue, for the one thing that is neither good, bad, a warning nor
     information: a partner agency. It had no token, so it was written out as
     #faf5ff in some places and #f3e8ff in others. */
  --purple:         #6b46c1;  --purple-bg:  #f3e8ff;  --purple-line: #ddc9f5;
  --accent-line:    #f5bcd5;   /* the pink chip's line, to match the four above */

  /* -- type -------------------------------------------------------------- */
  /* Reference numbers, hashes and amounts that get read out over the
     telephone. One stack, so a case number looks the same on every page. */
  --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  /* --- SPACING & SIZES --- */
  --radius: 10px;
  --shadow-sm: 0 1px 2px rgba(20, 24, 31, .06), 0 1px 3px rgba(20, 24, 31, .08);
  --shadow-md: 0 4px 6px rgba(20, 24, 31, .04), 0 10px 20px -6px rgba(20, 24, 31, .14);
  --container-width: 1200px;
  --header-height: 64px;
}

/* ==========================================================================
   The same interface, after dark
   ==========================================================================

   Nothing below this block knows about it. Every colour in the desk is one of
   the tokens above - that was the point of writing them down - so a second
   set of values under a class on <html> is the whole feature. What is not a
   token still is not: a stylesheet that writes #fff directly goes on writing
   white, which is why those are being worked out of the page styles.

   Three settings, and the third is the one people actually want:

     .theme-light   light, whatever the device says
     .theme-dark    dark, whatever the device says
     .theme-auto    whatever the device says

   The class is printed by the server from a cookie (app/views/layout.php), not
   set by a script after the page has painted. A dark page that flashes white
   for a tenth of a second on every single load is worse than no dark mode -
   it is the one moment somebody is looking straight at it.

   Contrast is held to the same rule as the light set: every text token at
   least 4.5:1 against the surface it sits on. Dark themes fail this more
   often than light ones, because pure white on pure black reads as glare and
   the usual fix is to lighten the background rather than to calm the text. */

/* One list of values, applied by either of the two ways of asking for it.
   Written twice because a selector list cannot be built out of a media query;
   what must never happen is the two drifting apart, so they are next to each
   other and there is nothing between them. */
:root.theme-dark {
  /* A button, not a heading colour - white text sits on it. Lighter than
     the card so it still reads as a raised thing on a dark page. */
  --primary:        #334051;
  --primary-hover:  #3f4e63;
  --accent:         #f472b6;   /* 8.9:1 on the card colour below */
  --accent-strong:  #f9a8d4;
  --accent-light:   #3b1d2c;

  --bg-body:        #12151a;
  --bg-card:        #1a1f27;
  --bg-subtle:      #212731;
  --bg-muted:       #2a313d;

  --text-main:      #e6e9ee;   /* 13.1:1 on the card */
  --text-strong:    #f5f7fa;
  --text-muted:     #b3bcc9;   /*  7.6:1 */
  --text-faint:     #93a0b1;   /*  5.4:1 */
  --text-on-dark:   #ffffff;

  --text-on-state:  #12151a;
  --border:         #2f3743;
  --border-strong:  #434d5c;
  --border-focus:   #7aa7f0;

  --success:        #4ade80;  --success-bg: #14301f;
  --danger:         #fb7185;  --danger-bg:  #3a1720;
  --warning:        #fbbf24;  --warning-bg: #3a2a10;
  --info:           #7aa7f0;  --info-bg:    #16263f;

  /* Lines around the tinted chips. Lighter than the tint, darker than the
     text - the same job as in the light set, done with the two neighbours
     swapped round. */
  --success-line:   #2c5c40;
  --danger-line:    #6b2a35;
  --warning-line:   #6a5220;
  --info-line:      #2f4a70;

  --purple:         #c4b5fd;  --purple-bg:  #2b2242;  --purple-line: #453768;
  --accent-line:    #6b3450;

  /* A shadow is a darker version of what is behind it. On a dark page there
     is nothing darker, so depth has to come from the border instead - the
     usual black shadow simply disappears and every card goes flat. */
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, .5);
  --shadow-md: 0 4px 6px rgba(0, 0, 0, .4), 0 10px 20px -6px rgba(0, 0, 0, .6);

  color-scheme: dark;
}

@media (prefers-color-scheme: dark) {
  :root.theme-auto {
    --primary:        #334051;
    --primary-hover:  #3f4e63;
    --accent:         #f472b6;
    --accent-strong:  #f9a8d4;
    --accent-light:   #3b1d2c;

    --bg-body:        #12151a;
    --bg-card:        #1a1f27;
    --bg-subtle:      #212731;
    --bg-muted:       #2a313d;

    --text-main:      #e6e9ee;
    --text-strong:    #f5f7fa;
    --text-muted:     #b3bcc9;
    --text-faint:     #93a0b1;
    --text-on-dark:   #ffffff;

    --text-on-state:  #12151a;
    --border:         #2f3743;
    --border-strong:  #434d5c;
    --border-focus:   #7aa7f0;

    --success:        #4ade80;  --success-bg: #14301f;
    --danger:         #fb7185;  --danger-bg:  #3a1720;
    --warning:        #fbbf24;  --warning-bg: #3a2a10;
    --info:           #7aa7f0;  --info-bg:    #16263f;

    --success-line:   #2c5c40;
    --danger-line:    #6b2a35;
    --warning-line:   #6a5220;
    --info-line:      #2f4a70;

    --purple:         #c4b5fd;  --purple-bg:  #2b2242;  --purple-line: #453768;
    --accent-line:    #6b3450;

    --shadow-sm: 0 1px 2px rgba(0, 0, 0, .5);
    --shadow-md: 0 4px 6px rgba(0, 0, 0, .4), 0 10px 20px -6px rgba(0, 0, 0, .6);

    color-scheme: dark;
  }
}

/* Photographs and scans of documents are not part of the interface and are
   left exactly as they are - a passport copy dimmed to fit a colour scheme is
   a passport copy somebody cannot read. */
:root.theme-dark img:not(.uv-dim),
:root.theme-auto img:not(.uv-dim) { filter: none; }

/* --- RESET & BASE --- */
*, *::before, *::after { box-sizing: border-box; }

body {
  font-family: 'Inter', -apple-system, system-ui, sans-serif;
  background-color: var(--bg-body);
  color: var(--text-main);
  line-height: 1.5;
  margin: 0;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

a { color: var(--info); text-decoration: none; transition: all 0.2s; }
a:hover { color: var(--text-main); text-decoration: none; }

/* The bar is a light surface now - the dark one moved to the column on the
   left - so the name up here reads as ordinary strong text again. */
.topbar a, .topbar .userbox strong { color: var(--text-strong); }
.topbar a:hover { color: var(--text-main); }

/* text-strong, not primary. --primary is the background of the primary
   button as well as the colour of a heading, and in a dark theme those two
   want opposite values - white text on a light button, or a heading nobody
   can read. They are two different things and now say so. */
h1, h2, h3, h4 { margin: 0 0 1rem 0; color: var(--text-strong); font-weight: 700; }
h1 { font-size: 1.85rem; letter-spacing: -0.025em; }

/* --- THE BAR ABOVE THE PAGE ---
   Everything that is a page is in the column on the left (resources/css/
   layout.css, section 7). What is left here is the search, the translator and
   who is logged in - so the bar may be quiet, light and shorter than it was. */
.topbar {
  background: var(--bg-card);
  min-height: 56px;
  color: var(--text-main);
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0 18px;
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 0;
  z-index: 900;
}

/* Only still used on the login page, where there is no column to put it in. */
.topbar .brand {
  font-weight: 800;
  text-transform: uppercase;
  /* Size and spacing come from resources/css/layout.css, where the name is
     stacked over two lines. */
}

.topbar .userbox {
  display: flex;
  align-items: center;
  gap: 15px;
  font-size: 0.85rem;
  margin-left: auto;
}

/* --- ACTION BAR (Search + Button Inline) --- */
.action-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 15px;
  margin-bottom: 25px;
  flex-wrap: nowrap;
}

.search-row {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: 1;
}

.search-row input { 
  margin-bottom: 0 !important;
  flex: 1;
}

/* --- GRID & LAYOUT --- */
.container {
  max-width: var(--container-width);
  margin: 20px auto;
  padding: 0 15px;
}

.grid2 {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 20px;
}

.admin-stats-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 20px;
  margin-bottom: 30px;
}

.stat-card {
  background: var(--bg-card);
  padding: 20px;
  border-radius: var(--radius);
  border-bottom: 4px solid var(--accent);
  box-shadow: var(--shadow-sm);
  text-align: center;
}

.stat-card .number { font-size: 2.2rem; font-weight: 800; display: block; }
.stat-card .label { color: var(--text-muted); font-size: 0.75rem; text-transform: uppercase; }

.grid-case-layout {
  display: grid;
  grid-template-columns: 1fr 320px;
  gap: 24px;
}

/* --- COMPONENTS: CARDS --- */
.card {
  background: var(--bg-card);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  padding: 20px;
  margin-bottom: 20px;
  border: 1px solid var(--border);
}

.doc-link-container {
    display: flex;
    align-items: center;
    max-width: 100%; 
    overflow: hidden;
}

.doc-link {
    font-weight: bold;
    color: var(--info);
    text-decoration: none;
    word-break: break-all; 
    overflow-wrap: break-word;
}

.docs-list {
    display: flex;
    flex-direction: column;
    gap: 8px;
    width: 100%;
}

/* --- COMPONENTS: BUTTONS --- */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--primary); color: var(--text-on-dark);
  border: none; border-radius: 6px;
  padding: 10px 18px;
  font-size: 0.9rem; font-weight: 600;
  cursor: pointer; transition: all 0.2s;
  gap: 8px;
  white-space: nowrap;
}
.btn:hover { background: var(--primary-hover); transform: translateY(-1px); box-shadow: var(--shadow-md); }
.btn.secondary { background: var(--border); color: var(--text-main); }
.btn.success { background: var(--success); color: var(--text-on-state); }
.btn.danger { background: var(--danger); color: var(--text-on-state); }
.btn.small { padding: 6px 12px; font-size: 0.8rem; }

/* --- COMPONENTS: TABLES --- */
.table-container {
  width: 100%;
  overflow-x: auto;
  border-radius: var(--radius);
  border: 1px solid var(--border);
  background: var(--bg-card);
  margin-bottom: 20px;
}
.table { width: 100%; border-collapse: collapse; }
.table th { 
  background: var(--bg-subtle); padding: 12px 15px; text-align: left; 
  font-size: 0.75rem; text-transform: uppercase; color: var(--text-muted);
  border-bottom: 2px solid var(--border);
}
.table td { padding: 15px; border-bottom: 1px solid var(--border); vertical-align: middle; }
.table tr:last-child td { border-bottom: none; }

/* --- BADGES --- */
.badge {
  display: inline-block; padding: 4px 10px;
  border-radius: 20px;
  font-size: 0.75rem; font-weight: 700;
  background: var(--border); color: var(--text-main);
  white-space: nowrap;
}
.badge.secondary { background: var(--border); color: var(--text-muted); }

/* --- COMPONENTS: FORMS --- */

/* The base rule stays deliberately plain (one element selector). A chain of
   :not() would look tidier but every :not([type=…]) adds the specificity of
   an attribute selector, and the rule would then beat page rules such as
   .adm-search input - the search field lost its padding that way.
   Checkboxes and radios are taken back out below instead. */
input, select, textarea {
  width: 100%;
  padding: 12px;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 0.95rem;
  margin-bottom: 10px;
  background: var(--bg-card);
}
input:focus { border-color: var(--info); outline: none; box-shadow: 0 0 0 3px rgba(49, 130, 206, 0.1); }

/* Checkboxes and radios keep their intrinsic size. Without this they inherit
   width:100% and padding:12px from the rule above, and a checkbox then pushes
   its own label out of the container - that is what broke the "Active" fields
   in the admin forms. Several pages worked around it with their own
   input[type=checkbox] rules; those are now redundant but harmless. */
input[type=checkbox], input[type=radio] {
  width: 16px; height: 16px;
  flex: none;
  margin: 0; padding: 0;
  border: 0; border-radius: 0; background: none;
  accent-color: var(--accent);
  cursor: pointer;
}
input[type=checkbox]:focus, input[type=radio]:focus {
  box-shadow: none; outline: 2px solid var(--info); outline-offset: 1px;
}

/* --- CHAT AREA --- */
.chat-container {
  background: var(--bg-subtle);
  border: 2px solid var(--border);
  border-radius: var(--radius);
  margin-bottom: 15px;
  overflow: hidden;
}
.chat-list { 
  display: flex; flex-direction: column; gap: 12px;
  max-height: 400px; overflow-y: auto; padding: 20px;
}
.chat-list::-webkit-scrollbar { width: 8px; }
.chat-list::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 10px; }

.chat-controls {
  display: flex;
  align-items: center;
  gap: 15px;
  margin-top: 10px;
  flex-wrap: nowrap; 
  background: var(--bg-card);
  padding: 5px 0;
}

.chat-controls label.inline-checkbox {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  white-space: nowrap;
  cursor: pointer;
  font-size: 0.9rem;
  font-weight: 500;
}

.chat-controls input[type="checkbox"] {
  width: 18px;
  height: 18px;
  margin: 0;
  cursor: pointer;
}

.chat-controls select {
  margin-bottom: 0 !important;
  width: auto;
  padding: 6px 10px;
  height: 36px;
}

.chat-controls .btn {
  white-space: nowrap;
}

.msg-row {
  max-width: 85%; padding: 12px 16px; border-radius: 12px; font-size: 0.95rem;
  box-shadow: 0 2px 4px rgba(0,0,0,0.05);
}
.msg-staff { background: var(--bg-card); align-self: flex-start; border: 1px solid var(--border); border-bottom-left-radius: 2px; }
.msg-customer { background: var(--info-bg); align-self: flex-end; border: 1px solid var(--info-line); border-bottom-right-radius: 2px; }

/* --- HISTORY / TIMELINE --- */
.timeline-item { position: relative; padding-bottom: 25px; padding-left: 25px; border-left: 2px solid var(--border); margin-left: 10px; }
.timeline-item::before {
  content: ''; position: absolute; left: -9px; top: 0;
  width: 16px; height: 16px; background: var(--bg-card);
  border: 3px solid var(--info); border-radius: 50%;
}
.timeline-card {
  background: var(--bg-card); border: 1px solid var(--border);
  padding: 15px; border-radius: 8px; font-size: 0.85rem;
  box-shadow: var(--shadow-sm);
}

/* --- TABS --- */
.tabs {
  display: flex; gap: 5px; border-bottom: 1px solid var(--border);
  margin-bottom: 20px; overflow-x: auto;
}
.tab-btn {
  padding: 12px 18px; border: none; background: none; cursor: pointer;
  color: var(--text-muted); font-weight: 600; border-bottom: 3px solid transparent;
  white-space: nowrap;
}
.tab-btn.active { color: var(--accent); border-bottom-color: var(--accent); }

/* --- MOBILE OPTIMIZATIONS --- */
@media (max-width: 768px) {
  /* The bar no longer stacks - it holds four things and they fit in a row.
     The menu that used to make it stack is a column now. */
  .topbar { height: auto; padding: 10px 12px; }
  .topbar .userbox { gap: 8px; }
  /* The name is a link to the profile and the button says "log out" - on a
     narrow bar the button is enough, and the name is one tap away in there. */
  .topbar .userbox a { display: none; }

  /* Written as ".container .action-bar", and everything in the block below
     the same way, for one dull reason: the page stylesheets load after this
     file and set these same classes without a media query. A rule in here
     with the same weight loses to them no matter what it says. Naming the
     wrapper the page is already inside settles it without !important, which
     would only move the argument somewhere else. */
  .container .action-bar { flex-direction: column; align-items: stretch; gap: 10px; margin-bottom: 12px; }
  .container .action-bar h1 { margin: 0; }
  .search-row { width: 100%; }
  .grid-case-layout { grid-template-columns: 1fr; }
  .sidebar { order: -1; }

  /* --- THE HEAD OF A LIST PAGE -------------------------------------------
     The case list and the customer list are built the same way and were
     each carrying their own copy of these rules. One copy now, here, where
     .action-bar above already lives - two copies of a layout rule is two
     places to forget.

     What was wrong with them: the search box, the button and five dropdowns
     each took a row of their own, so the first case was a screen and a half
     down, and the quick filters wrapped - "Visa Expiring Watchlist" came
     out as three lines of red underneath two other broken ones. */

  .container .search-container-top { max-width: 100%; }

  .container .filter-container { padding: 12px; margin-bottom: 14px; }

  /* A strip that scrolls sideways instead of wrapping: each filter stays
     one word-shaped thing to tap. The negative margin lets it run to both
     edges of the card, so it is visibly scrollable rather than looking cut
     off. */
  .container .quick-filters {
    flex-wrap: nowrap;
    overflow-x: auto;
    gap: 16px;
    margin: 0 -12px 12px;
    padding: 0 12px 10px;
    scrollbar-width: none;
  }
  .container .quick-filters::-webkit-scrollbar { display: none; }
  .container .quick-filter-item { flex: none; white-space: nowrap; }

  /* Two dropdowns across rather than five down. Every label still fits;
     what goes away is half the scrolling before the list starts. */
  .container .filter-flex {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 10px;
    align-items: end;
  }
  .container .filter-flex .filter-item { min-width: 0; }
  .container .filter-flex .filter-item select { width: 100%; }
  .container .filter-flex .spacer { display: none; }
  /* "137 results" belongs under them, across the whole width. */
  .container .filter-flex > .small.muted { grid-column: 1 / -1; }

  .table thead { display: none; }
  .table tr { display: block; border: 1px solid var(--border); margin-bottom: 10px; border-radius: var(--radius); padding: 10px; background: var(--bg-card); }
  .table td { display: flex; justify-content: space-between; padding: 8px 5px; border: none; font-size: 0.9rem; text-align: right; }
  .table td::before { content: attr(data-label); font-weight: 700; color: var(--text-muted); float: left; }

  .chat-controls {
    flex-direction: column; 
    align-items: stretch;
  }
  .chat-controls .spacer {
    display: none;
  }
  .chat-controls select, .chat-controls .btn {
    width: 100%;
  }
}

/* --- WIKI SPECIFIC --- */
.wiki-content { line-height: 1.8; font-size: 1.1rem; }

/* Mobile Table Transformation
   ---------------------------------------------------------------------------
   A table row becomes a card: the column headings disappear and each cell
   carries its own label instead. That part was right. What it cost was width.

   A card list on a phone was sitting inside four nested frames - the page
   container's 15px, the box drawn around the whole table, the card's own
   border, and the cell's padding. Thirty-two pixels down each side of a
   390px screen: a sixth of the screen spent on edges, and the customer's
   name wrapping because of it.

   The row already has a border. The box around all of them is a second
   frame saying the same thing, so on a phone the list pages mark their
   container "is-cards" and it steps out of the way. */
@media screen and (max-width: 768px) {
    /* Every pixel here is one the names and dates do not get. */
    .container { padding: 0 8px; }

    .table-container.is-cards {
        border: none;
        background: none;
        border-radius: 0;
        overflow-x: visible;   /* nothing reaches sideways once it is cards */
        margin-bottom: 12px;
    }

    .table.mobile-cards thead { display: none; }

    /* The table and its body become blocks as well, not only the rows. While
       they stayed a table, the browser kept building anonymous table boxes
       around the block rows, and a margin on a cell inside one of those is
       ignored - which is why the heading strip of each card stopped short of
       the right-hand edge instead of reaching it. */
    .table.mobile-cards,
    .table.mobile-cards tbody { display: block; width: 100%; }

    .table.mobile-cards tr { display: block; margin-bottom: 10px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg-card); padding: 10px 12px; box-shadow: var(--shadow-sm); }
    .table.mobile-cards td { display: flex; justify-content: space-between; align-items: center; gap: 10px; text-align: right; padding: 7px 0; border-bottom: 1px solid var(--border); max-width: 100% !important; }
    .table.mobile-cards td:last-child { border-bottom: none; }
    .table.mobile-cards td::before { content: attr(data-label); font-weight: bold; text-transform: uppercase; font-size: 0.7rem; color: var(--text-muted); text-align: left; flex: none; }

    /* The heading of the card: the case or the customer, across the full
       width with no label of its own - it is the thing, not a field of it.

       This used to be selected with [data-label="Case"], which is the
       English word. On a German or Thai desk it matched nothing and the
       card had no heading. It is a class now, so it works in every
       language the desk speaks. */
    .table.mobile-cards td.cell-primary {
        flex-direction: column; align-items: stretch; text-align: left;
        background: var(--bg-subtle);
        margin: -10px -12px 10px -12px;
        /* The cells above are held to "max-width: 100% !important" so a long
           value cannot push the card wider than the screen. This one is meant
           to be wider than its box - that is what the negative margins are
           for - and the cap was quietly undoing them, leaving the heading
           strip short of the card's right-hand edge. */
        max-width: none !important;
        padding: 12px;
        border-radius: var(--radius) var(--radius) 0 0;
    }
    .table.mobile-cards td.cell-primary::before { display: none; }
}

/* CALENDAR MOBILE FIX */
@media (max-width: 650px) {
    .fc .fc-toolbar { display: flex !important; flex-direction: column !important; gap: 8px !important; }
    .fc-toolbar-chunk { display: flex !important; justify-content: center !important; width: 100% !important; }
    .fc-toolbar-title { font-size: 1.1rem !important; }
    .fc-list-event-time { width: 60px !important; }
}

/* --- UTILITIES & ICONS --- */
.mobile-header { display: flex; justify-content: space-between; width: 100%; align-items: center; }
.action-flex { display: flex; gap: 6px; align-items: center; justify-content: flex-end; }
.action-flex form.inline { margin: 0; display: flex; }
.btn-icon { width: 32px; height: 32px; display: inline-flex; align-items: center; justify-content: center; border-radius: var(--radius); border: none; cursor: pointer; transition: transform 0.1s ease, opacity 0.2s; padding: 0; text-decoration: none; }
.btn-icon:active { transform: scale(0.9); }
.btn-icon:hover { opacity: 0.9; }
.btn-icon svg { width: 18px; height: 18px; display: block; }
.btn-icon.success { background-color: var(--success); color: white; }
.btn-icon.danger  { background-color: var(--danger); color: white; }
.btn-icon.secondary { background-color: var(--border); color: var(--text-main); }

/* ALERTS */
.alert { padding: 12px 16px; border-radius: var(--radius); margin-bottom: 20px; font-weight: 500; border: 1px solid transparent; display: flex; align-items: center; }
.alert.success { background-color: var(--success-bg); color: var(--success); border-color: var(--success); }
.alert.error { background-color: var(--danger-bg); color: var(--danger); border-color: var(--danger); }

/* MODAL / Z-INDEX STICKY FIX */
/* Keeps modals from ending up behind the fixed topbar */
.modal-overlay, .fc-modal, .modal-box {
  z-index: 3000 !important;
}