/* ===========================================================================
   The Green TV — upload console skin.

   File Browser themes itself from a handful of CSS custom properties, so the
   brand is applied by redefining those rather than by chasing individual
   classes. That re-skins the file listing, the toolbars, the dialogs and the
   upload tray as well as the login page, and it keeps working if the markup
   changes underneath.
   ========================================================================= */

@import url('https://fonts.googleapis.com/css2?family=Hanken+Grotesk:wght@400;500;600;700&family=Bricolage+Grotesque:opsz,wght@12..96,600;12..96,700&display=swap');

:root {
  /* Brand */
  --gtv-leaf:      #5AAE30;
  --gtv-leaf-hi:   #84D24A;
  --gtv-leaf-deep: #3C7D1F;
  --gtv-ink:       #07110C;
  --gtv-surface:   #112019;
  --gtv-surface-2: #172E23;
  --gtv-cloud:     #E9F5EC;

  --gtv-ui:      'Hanken Grotesk', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --gtv-display: 'Bricolage Grotesque', var(--gtv-ui);
}

/* ---- File Browser's own tokens, repainted in the brand palette ----------
   File Browser puts its dark palette on `:root.dark`, not on `:root`. A plain
   `:root` block here would lose on specificity and only the login page would
   have changed, so both selectors are named. They tie with the originals on
   specificity and this stylesheet is linked last, so these win. */
:root,
:root.dark {
  --background:       var(--gtv-ink);
  --surfacePrimary:   var(--gtv-surface);
  --surfaceSecondary: var(--gtv-surface-2);

  /* The accent is used for buttons, links, progress and the active state.
     Everything that was Material blue becomes leaf green. */
  --blue:       var(--gtv-leaf);
  --dark-blue:  var(--gtv-leaf-deep);
  --icon-blue:  var(--gtv-leaf-hi);
  --iconPrimary: var(--gtv-leaf-hi);

  --textPrimary:   rgba(233, 245, 236, 0.60);
  --textSecondary: rgba(233, 245, 236, 0.93);
  --iconSecondary: rgba(233, 245, 236, 0.80);
  --iconTertiary:  rgba(233, 245, 236, 0.55);

  --divider:         rgba(132, 210, 74, 0.13);
  --dividerPrimary:  rgba(132, 210, 74, 0.30);
  --borderPrimary:   rgba(132, 210, 74, 0.09);
  --borderSecondary: rgba(132, 210, 74, 0.20);
  --hover:           rgba(132, 210, 74, 0.10);
  --item-selected:   rgba(90, 174, 48, 0.20);

  --icon-green: var(--gtv-leaf-hi);
  --input-green: #16401F;
}

body {
  font-family: var(--gtv-ui);
  background: var(--gtv-ink);
  color: var(--gtv-cloud);
  -webkit-font-smoothing: antialiased;
}

/* The aurora lives on the page, not on #login: that element is a nested div
   sized to its card, so a gradient set there was trapped in a box around the
   form instead of washing the whole screen. */
body:has(#login) {
  background:
    radial-gradient(1200px 700px at 50% -10%,  rgba(90, 174, 48, 0.30), transparent 60%),
    radial-gradient(900px 620px at 6% 106%,   rgba(60, 125, 31, 0.26), transparent 58%),
    radial-gradient(900px 620px at 96% 100%,  rgba(132, 210, 74, 0.15), transparent 58%),
    var(--gtv-ink);
  background-attachment: fixed;
}

/* A single hairline of brand colour across the very top of the page. */
body:has(#login)::before {
  content: '';
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  z-index: 10;
  background: linear-gradient(90deg,
    transparent, var(--gtv-leaf) 20%, var(--gtv-leaf-hi) 50%, var(--gtv-leaf) 80%, transparent);
}

/* =========================================================================
   Login
   ========================================================================= */

/* A quiet aurora behind the card: two soft green lights over near-black,
   so the page reads as "Green TV" before a single word is read. */
#login { background: transparent; position: relative; }

#login form {
  background: linear-gradient(180deg, rgba(23, 46, 35, 0.92), rgba(17, 32, 25, 0.92));
  border: 1px solid rgba(132, 210, 74, 0.18);
  border-radius: 20px;
  padding: 2.4rem 2.1rem 2rem;
  width: min(92vw, 420px) !important;
  max-width: min(92vw, 420px) !important;
  box-sizing: border-box;
  box-shadow:
    0 28px 70px rgba(0, 0, 0, 0.55),
    0 0 0 1px rgba(255, 255, 255, 0.02) inset;
  backdrop-filter: blur(8px);
}

/* The mark, on its own plate so the white leaf keeps its contrast. */
#login img {
  width: 84px;
  height: 84px;
  margin: 0 auto 1.1rem;
  display: block;
  border-radius: 18px;
  box-shadow: 0 10px 28px rgba(90, 174, 48, 0.35);
}

#login h1 {
  font-family: var(--gtv-display);
  font-weight: 700;
  font-size: 1.45rem;
  line-height: 1.22;
  letter-spacing: -0.015em;
  color: var(--gtv-cloud);
  margin: 0 0 1.45rem;
  text-align: center;
}

/* A line of orientation, directly under the title. It hangs off the heading
   rather than the form: on the form it became the last child and sat below
   the Login button, which read as a caption for the button. */
#login h1::after {
  content: 'Secure upload for the production team';
  display: block;
  margin-top: 0.5rem;
  font-family: var(--gtv-ui);
  font-weight: 500;
  font-size: 0.8rem;
  line-height: 1.45;
  letter-spacing: 0;
  color: rgba(233, 245, 236, 0.5);
}

#login input[type="text"],
#login input[type="password"],
#login input.input {
  background: rgba(7, 17, 12, 0.72);
  border: 1px solid rgba(132, 210, 74, 0.20);
  border-radius: 11px;
  color: var(--gtv-cloud);
  font-family: var(--gtv-ui);
  font-size: 0.95rem;
  padding: 0.85rem 1rem;
  margin-bottom: 0.7rem;
  transition: border-color 0.15s ease, box-shadow 0.15s ease, background 0.15s ease;
}

#login input.input::placeholder { color: rgba(233, 245, 236, 0.34); }

#login input.input:focus {
  outline: none;
  background: rgba(7, 17, 12, 0.92);
  border-color: var(--gtv-leaf);
  box-shadow: 0 0 0 3px rgba(90, 174, 48, 0.20);
}

/* The stock rule for this button is `.button` painted from --surfacePrimary,
   which ties with `#login button` on nothing and beat it. Hence !important on
   the paint properties: the brand action has to be unmistakably the brand. */
#login button,
#login .button,
#login input.button,
#login input[type="submit"] {
  background: linear-gradient(180deg, var(--gtv-leaf-hi), var(--gtv-leaf)) !important;
  border: none !important;
  border-radius: 11px !important;
  color: #06230D !important;
  font-family: var(--gtv-ui);
  font-weight: 700;
  font-size: 0.97rem;
  letter-spacing: 0.01em;
  padding: 0.88rem 1rem;
  margin-top: 0.3rem;
  cursor: pointer;
  transition: transform 0.12s ease, box-shadow 0.18s ease, filter 0.15s ease;
  box-shadow: 0 10px 24px rgba(90, 174, 48, 0.30) !important;
}

#login .button:hover, #login button:hover { filter: brightness(1.07); box-shadow: 0 13px 30px rgba(90, 174, 48, 0.40) !important; }
#login .button:active, #login button:active { transform: translateY(1px); }

#login .wrong {
  background: #5A1A16;
  border-radius: 10px;
  color: #FFD9D5;
}

/* =========================================================================
   Inside — the file area
   ========================================================================= */

header,
#search,
nav,
.dashboard,
#file-selection {
  font-family: var(--gtv-ui);
}

/* The top bar carries a thin brand edge, matching the login page. */
header {
  background: linear-gradient(180deg, var(--gtv-surface-2), var(--gtv-surface)) !important;
  border-bottom: 1px solid rgba(132, 210, 74, 0.16);
}

header .topbar-title,
header img {
  filter: drop-shadow(0 2px 6px rgba(0, 0, 0, 0.35));
}

/* Search reads as a field rather than a floating label. */
#search #input {
  background: rgba(7, 17, 12, 0.6);
  border: 1px solid rgba(132, 210, 74, 0.16);
  border-radius: 11px;
}

/* Listing: give rows room to breathe and a green selection state. */
#listing.list .item {
  border-radius: 10px;
  border-bottom: 1px solid rgba(132, 210, 74, 0.08);
}

#listing .item[aria-selected="true"],
#listing .item.selected {
  background: rgba(90, 174, 48, 0.18) !important;
  box-shadow: inset 2px 0 0 var(--gtv-leaf-hi);
}

#listing .item:hover { background: rgba(132, 210, 74, 0.08); }

/* Folders in brand green, files in a calm neutral, so a day's folder is easy
   to pick out of a long list. */
#listing .item[data-dir="true"] i { color: var(--gtv-leaf-hi) !important; }

/* Buttons and the floating action button. */
.button--flat { color: var(--gtv-leaf-hi) !important; border-radius: 10px; }
.button--flat:hover { background: rgba(132, 210, 74, 0.12) !important; }

.action:hover { background: rgba(132, 210, 74, 0.12); }

/* Progress bars. The storage gauge in the sidebar and the upload bars are
   drawn by vue-simple-progress, which writes its colours as inline styles
   (a #eee track and Material blue #2196f3 fill). Inline styles lose to an
   !important rule in a stylesheet, which is the only way to reach them. */
.vue-simple-progress {
  background: rgba(132, 210, 74, 0.16) !important;
  border-radius: 3px;
  overflow: hidden;
}

.vue-simple-progress-bar {
  background: linear-gradient(90deg, var(--gtv-leaf), var(--gtv-leaf-hi)) !important;
  border-radius: 3px;
}

#progress > div,
.upload-info progress::-webkit-progress-value {
  background: linear-gradient(90deg, var(--gtv-leaf), var(--gtv-leaf-hi)) !important;
}

/* The sidebar footer text sat at near-full white against the dark panel. */
.credits { color: rgba(233, 245, 236, 0.45); }
.credits a { color: var(--gtv-leaf-hi); }

/* ---- what the camera team is offered ------------------------------------
   The cameraman has no business in the settings screen. His account reaches
   it only by clicking his own name at the top of the sidebar, so that entry
   is removed for anyone who is not an admin.

   Admin and non-admin are told apart without any server help: File Browser
   only puts a "Settings" button in an admin's sidebar, so `:has()` on that
   button is a reliable test. The admin keeps the profile link and the
   Settings screen; the cameraman gets files and nothing else.

   This is presentation only. The one setting that actually mattered - his
   password - is locked on the server with lockPassword, which is what stops
   him changing the credential he was issued. */
nav:not(:has(button[aria-label="Settings"])) > button.action:first-of-type {
  display: none;
}

/* And if the settings URL is typed in by hand, there is nothing on it for a
   non-admin either. The settings screens live in `.dashboard`; dialogs are
   `.card.floating` inside `#modal-background`, so New folder, rename and the
   upload prompts are untouched by this. */
body:not(:has(nav button[aria-label="Settings"])) .dashboard > *:not(header) {
  /* !important because the tab strip sets display:flex from a more specific
     rule and was the one child that stayed on screen. The page's own header
     is kept, otherwise the screen looks broken rather than deliberately bare. */
  display: none !important;
}

body:not(:has(nav button[aria-label="Settings"])) .dashboard::after {
  content: 'Settings are managed by The Green TV. Use "My files" to upload your footage.';
  display: block;
  max-width: 34rem;
  margin: 3rem auto;
  padding: 1.6rem 1.8rem;
  text-align: center;
  background: var(--gtv-surface);
  border: 1px solid rgba(132, 210, 74, 0.16);
  border-radius: 16px;
  color: rgba(233, 245, 236, 0.62);
  font-size: 0.95rem;
  line-height: 1.5;
}

/* The tool's name and version line. `div.credits` is the storage gauge and
   `p.credits` is the footer, so this hides only the latter. An outside
   contractor has no use for the software's name, and the version of an
   archived build is not worth advertising. */
p.credits { display: none; }

/* Dialogs and the upload tray. */
.card,
.upload-info {
  background: var(--gtv-surface) !important;
  border: 1px solid rgba(132, 210, 74, 0.16);
  border-radius: 16px;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.5);
}

.card h2,
.card h3 { font-family: var(--gtv-display); color: var(--gtv-cloud); }

/* Material's blue ripple/accent shows through in a few spots. */
.card-action button:not(.button--grey) { color: var(--gtv-leaf-hi) !important; }

/* Phone: the login card should not be pinned to the viewport edges. */
@media (max-width: 520px) {
  #login form { padding: 1.9rem 1.4rem 1.6rem; border-radius: 16px; }
  #login h1 { font-size: 1.3rem; }
  #login img { width: 64px; height: 64px; }
}
