/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

/* Label/tag denoting the user that shared a connection */
.jdbc-share-tag {

    background: #0095ff;
    padding: 0.25em;

    -moz-border-radius:    0.25em;
    -webkit-border-radius: 0.25em;
    -khtml-border-radius:  0.25em;
    border-radius:         0.25em;

    color: white;
    font-size: 0.75em;
    font-weight: bold;

}
.totp-enroll p,.totp-details{font-size:.8em}.totp-qr-code{text-align:center}.totp-qr-code img{margin:1em;border:1px solid rgba(0,0,0,0.25);box-shadow:1px 1px 2px rgba(0,0,0,0.25);cursor:pointer}h3.totp-details-header{font-size:.8em}h3.totp-details-header::before{content:'▸ '}.totp-details-visible h3.totp-details-header::before{content:'▾ '}.totp-details,.totp-hide-details{display:none}.totp-details-visible .totp-details{display:table}.totp-details-visible .totp-hide-details{display:inline}.totp-details-visible .totp-show-details{display:none}.totp-hide-details,.totp-show-details{color:blue;text-decoration:underline;cursor:pointer;margin:0 .25em;font-weight:normal}.totp-details{margin:0 auto}.totp-details th{padding-right:.25em;text-align:left}.totp-details td{font-family:monospace}.totp-detail{display:inline-block;margin:0 .25em}/* Pesaranlab Desktop Theme — Guacamole extension (guac-manifest.json "css"/"js"
 * resources). theme.css is pure CSS, loaded after Guacamole's own bundle so
 * equal-specificity rules already win on cascade order; every selector below is
 * still scoped under `.login-ui` or `.home-view` anyway, both belt-and-suspenders
 * for specificity AND to keep this from ever touching a live remote-desktop session's UI.
 *
 * Supersedes desktop-picker-banner.jar (2026-08-22), which injected a "choosing a
 * desktop? -mate vs -xfce" notice above the connection list. Removed at request
 * 2026-08-28. A point-and-click "+ Add another desktop" widget briefly lived here
 * (2026-08-29) but was pulled the same day at request -- bijan didn't want a
 * dedicated region at the top of the connection list for it; multi-desktop
 * provisioning stays available via the guac_add_desktop bot tool / server-mcp
 * (same underlying guac-provision-user call, no UI regression in capability).
 *
 * expand-groups.js (sibling file) auto-expands the "ALL CONNECTIONS" lab-group
 * folders on page load -- pure DOM click-simulation, no styling of its own needed.
 *
 * Design tokens mirror register.pesaranlab.org's (~/scripts/login-onboarding-server.py,
 * PAGE_CSS) so the two halves of one onboarding->desktop flow read as one product: same
 * IBM Plex Sans/Mono + Source Serif 4 pairing, same accent blue, same light/dark tokens,
 * same 8px/14px radius scale. Prefixed `--dpt-*` (not reusing register's bare `--accent`
 * etc.) since this stylesheet shares a global `:root` with the rest of Guacamole's own
 * CSS and must not collide with any variable name Guacamole itself defines.
 *
 * Selectors below were read directly out of the running container's exploded webapp
 * (`docker exec guacamole find /tmp/catalina-base.X/webapps/ROOT -iname '*.html'`, where
 * X is the per-run suffix Tomcat picks) and the app/*\/styles/*.css sources + the compiled
 * 1.guacamole.*.css bundle, not guessed from a
 * browser inspector -- re-check those templates if this ever stops matching after a
 * Guacamole image upgrade (currently pinned to `guacamole/guacamole:latest` == 1.6.0).
 */

@import url('https://fonts.googleapis.com/css2?family=Source+Serif+4:wght@500;600;700&family=IBM+Plex+Sans:wght@400;500;600&family=IBM+Plex+Mono:wght@500;600&display=swap');

:root {
  --dpt-bg:#FAFAF8; --dpt-surface:#FFFFFF; --dpt-ink:#1C1E24; --dpt-ink-muted:#6B7080;
  --dpt-border:#E3E1DC; --dpt-accent:#2451B0; --dpt-accent-ink:#FFFFFF;
  --dpt-err:#B23B3B; --dpt-err-bg:#FBEDEC; --dpt-hover-bg:#F1EFE9;
}
@media (prefers-color-scheme:dark) {
  :root {
    --dpt-bg:#14161C; --dpt-surface:#1B1E27; --dpt-ink:#E8E9ED; --dpt-ink-muted:#9498A8;
    --dpt-border:#2C303C; --dpt-accent:#7DA1EC; --dpt-accent-ink:#10131F;
    --dpt-err:#E1837F; --dpt-err-bg:#2A1918; --dpt-hover-bg:#232733;
  }
}

/* ---------------------------------------------------------------------------
 * Login screen (app/login/templates/login.html -> `.login-ui`)
 * --------------------------------------------------------------------------- */

/* `html body` prefix bumps specificity above core's own `div.login-ui{background:#fff}`
 * (a type+class selector, which would otherwise beat a bare `.login-ui` regardless of
 * stylesheet load order) rather than relying on cascade order alone. */
html body .login-ui {
  min-height:100vh; box-sizing:border-box; background:var(--dpt-bg);
  font-family:'IBM Plex Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
}

/* `.login-dialog` also carries Guacamole's own `.notification` class, which core CSS
 * gives an explicit `color:#000` -- an ancestor `color` (however set) never overrides a
 * rule that directly matches the element itself, so without this the whole dialog's text
 * stayed black no matter what `.login-ui` declared. */
.login-ui .login-dialog {
  background:var(--dpt-surface); color:var(--dpt-ink); border:1px solid var(--dpt-border);
  border-radius:14px; box-shadow:0 1px 2px rgba(20,22,30,.04),0 8px 28px rgba(20,22,30,.06);
}
@media (prefers-color-scheme:dark) {
  .login-ui .login-dialog { box-shadow:0 1px 2px rgba(0,0,0,.2),0 8px 28px rgba(0,0,0,.35); }
}

.login-ui .version .app-name {
  font:600 20px/1.25 'Source Serif 4',Georgia,'Times New Roman',serif;
  color:var(--dpt-ink); letter-spacing:-.01em;
}
.login-ui .version .version-number { color:var(--dpt-ink-muted); font-size:12px; }

.login-ui .login-error {
  color:var(--dpt-err); background:var(--dpt-err-bg); border-radius:8px;
  padding:10px 12px; font-size:13.5px; font-family:'IBM Plex Sans',sans-serif;
}

.login-ui .login-dialog label { color:var(--dpt-ink-muted); font:500 12px 'IBM Plex Sans',sans-serif; }

.login-ui .login-dialog .login-fields input {
  font-family:'IBM Plex Sans',sans-serif; color:var(--dpt-ink); background:var(--dpt-bg);
  border:1.5px solid var(--dpt-border); border-radius:8px;
}
.login-ui .login-dialog .login-fields input:focus {
  outline:2px solid var(--dpt-accent); outline-offset:1px; border-color:var(--dpt-accent);
}
/* Core CSS forces the field WHITE the moment it's focused or empty --
 * `.labeled-field.empty input{background:transparent}` and
 * `.labeled-field input:focus{background:#fff}` -- both higher specificity than the
 * plain rule above, so typing into ANY login field (username, password, the TOTP
 * "Authentication Code" box) flipped it to a white box still holding light dark-theme
 * text: pale-on-white, unreadable. `html body` + the `.labeled-field` step matches
 * core's own specificity (4 classes + the input type) so this wins in every state. */
html body .login-ui .login-dialog .login-fields .labeled-field input {
  background:var(--dpt-bg); color:var(--dpt-ink);
}
/* Browser default placeholder color (mid-gray, tuned for light backgrounds) reads at
 * ~3.6:1 against the dark input background -- below WCAG AA. Made explicit rather than
 * left to the browser default, which varies (and under-contrasts) across browsers. */
.login-ui .login-dialog .login-fields input::placeholder { color:var(--dpt-ink-muted); opacity:1; }

.login-ui .login-dialog .buttons input[type=submit] {
  font:600 15px 'IBM Plex Sans',sans-serif; background:var(--dpt-accent); color:var(--dpt-accent-ink);
  border:none; border-radius:8px; cursor:pointer;
}
.login-ui .login-dialog .buttons input[type=submit]:hover { filter:brightness(1.08); }
.login-ui .login-dialog .buttons input[type=submit]:focus-visible {
  outline:2px solid var(--dpt-accent); outline-offset:2px;
}

/* ---------------------------------------------------------------------------
 * Live desktop session (app/client/styles/client.css, tiled-client-grid.css) --
 * a genuine LAYOUT bug fix, not a cosmetic override, so it's deliberately NOT
 * scoped under `.login-ui`/`.home-view` like everything else in this file --
 * this is the one rule in this stylesheet that's meant to touch a live session.
 *
 * `.tiled-client-row` is `display:flex;flex-direction:row`, with `.client-tile`
 * and (nested inside it) `.main` both `flex:1`, eventually wrapping the actual
 * Guacamole display <canvas>. Flex items default to `min-width:auto`, and for
 * an element containing a replaced element with intrinsic size (a canvas whose
 * width/height attributes are set to the remote desktop's real pixel size,
 * e.g. ~1290px), that default floor resolves to the canvas's own width --
 * core CSS never overrides it with `min-width:0` anywhere in this chain.
 *
 * Confirmed 2026-08-30 (bijan): a portrait-oriented / narrow-aspect browser
 * window crops the right-hand columns of the desktop with NO scrollbar --
 * reloading the page and toggling "Auto-fit window" both had zero effect,
 * because Guacamole's own auto-fit scale computation (`main.offsetWidth /
 * display.getWidth()`) measures `main`'s width AFTER it's already been
 * floored by this same flex bug, so it thinks nothing needs to shrink. Once
 * the browser viewport is wide enough that the ~1290px floor doesn't bind
 * (landscape, or a wide-enough desktop window), the bug is invisible -- which
 * is exactly the "works in landscape, not portrait" pattern reported.
 *
 * Standard fix for this well-known flexbox gotcha: set `min-width:0` on every
 * flex item in the chain so it can actually shrink to fit its real container
 * instead of the canvas's intrinsic size. */
.tiled-client-grid .tiled-client-row,
.tiled-client-grid .client-tile,
.tiled-client-grid .client-tile .main {
  min-width: 0;
}

/* Live desktop session, continued (bijan, 2026-08-30): when the display isn't at exact
 * auto-fit scale, `.client-main.main` (guacClient.html's own root element, `main` in
 * guacClient.js) gets `overflow:auto` so you can scroll to the rest of the desktop --
 * but Guacamole's own touch handlers (guac-touch-drag/guac-touch-pinch, registered on
 * this same element) intercept swipes within the desktop area to drive the REMOTE mouse
 * cursor/pan, not the browser's native scroll. That leaves the scrollbar TRACK itself as
 * the only real way to pan on a touchscreen, and browsers' default scrollbar is a few px
 * wide -- not a usable touch target. Widened + made a fatter thumb so it can actually be
 * grabbed with a finger. WebKit-only pseudo-elements (`-webkit-scrollbar-*`) cover both
 * mobile engines that matter here (iOS Safari, Android Chrome); the standard
 * `scrollbar-width`/`scrollbar-color` properties are the closest Firefox equivalent
 * (Firefox has no way to set a specific pixel width, only 'thin'/'auto'/'none'). */
.client-main.main::-webkit-scrollbar {
  width: 22px;
  height: 22px;
}
.client-main.main::-webkit-scrollbar-track {
  background: rgba(0, 0, 0, 0.25);
}
.client-main.main::-webkit-scrollbar-thumb {
  background-color: rgba(255, 255, 255, 0.55);
  border-radius: 11px;
  border: 5px solid transparent;
  background-clip: padding-box;
}
.client-main.main::-webkit-scrollbar-thumb:active {
  background-color: rgba(255, 255, 255, 0.8);
}
.client-main.main {
  scrollbar-width: auto;
  scrollbar-color: rgba(255, 255, 255, 0.55) rgba(0, 0, 0, 0.25);
}

/* ---------------------------------------------------------------------------
 * Home / desktop-picker screen (app/home/templates/home.html -> `.home-view`)
 * `#other-connections` (the live-session client panel) is a SIBLING of `.home-view`
 * in index.html, not a descendant -- everything scoped under `.home-view` here is
 * inert during an actual remote-desktop session.
 * --------------------------------------------------------------------------- */

html body .home-view {
  min-height:100vh; box-sizing:border-box; background:var(--dpt-bg); color:var(--dpt-ink);
  font-family:'IBM Plex Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
}

.home-view .header h2 {
  font:600 17px/1.3 'Source Serif 4',Georgia,'Times New Roman',serif;
  color:var(--dpt-ink); letter-spacing:-.005em; margin:0.6em 0 0.4em;
}

.home-view .filter .search-string {
  font-family:'IBM Plex Sans',sans-serif; color:var(--dpt-ink); background:var(--dpt-surface);
  border:1.5px solid var(--dpt-border); border-radius:8px;
}
.home-view .filter .search-string:focus {
  outline:2px solid var(--dpt-accent); outline-offset:1px; border-color:var(--dpt-accent);
}
.home-view .filter .search-string::placeholder { color:var(--dpt-ink-muted); opacity:1; }

/* Every `<a>` in the home view (connection/group tiles, the profile name link, user-menu
 * items) needs an explicit color: core CSS only recolors `a` inside specific ancestors
 * (`.connection a`, `.menu-contents li a`, etc.) -- anything it misses, like the profile
 * `.full-name a`, falls through to the BROWSER'S DEFAULT LINK BLUE (~1.8:1 on a dark
 * background, effectively invisible), because a rule that directly matches an element
 * always wins over an inherited color, even the browser's own UA default for `:link`.
 * `html body` bumps specificity above `.connection a`/`.user a`/etc. (each a type+class
 * selector) rather than leaning on cascade order. */
html body .home-view a { color:var(--dpt-ink); }

/* Connection / connection-group rows (app/home/templates/connection*.html render as
 * `.list-item .caption`, from the shared `list` module -- generic list-item styling
 * lives in Guacamole's core bundle, e.g. `.list-item .caption:hover{background:#cda}`,
 * which these override on specificity via the `.home-view` prefix. */
.home-view .list-item .caption { border-radius:8px; transition:background .12s ease; }
.home-view .list-item .caption:hover { background:var(--dpt-hover-bg); }
.home-view .list-item.selected { background:var(--dpt-hover-bg); }
/* Not scoped to `.list-item` -- the Recent Connections row (`.recent-connections
 * .connection .name`) uses the same `.name` span but ISN'T wrapped in a `.list-item`
 * (that's specific to the group-list/"All Connections" section), so a `.list-item .name`
 * selector silently missed it: core's `.list-item .name{color:#000}` still won there,
 * leaving recent-connection names black-on-dark. */
.home-view .name { color:var(--dpt-ink); font-family:'IBM Plex Sans',sans-serif; }

/* User menu (top-right dropdown: settings/logout) */
.home-view .user-menu .menu-dropdown { background:transparent; border-left:1px solid var(--dpt-border); }
.home-view .user-menu .menu-dropdown:hover { background:var(--dpt-hover-bg); }
.home-view .user-menu .menu-dropdown.open,
.home-view .user-menu .menu-dropdown.open:hover { background:var(--dpt-accent); }
.home-view .user-menu .menu-dropdown.open .menu-title { color:var(--dpt-accent-ink); }
.home-view .menu-dropdown .menu-contents {
  background:var(--dpt-surface); border:1px solid var(--dpt-border); border-radius:8px;
  overflow:hidden; box-shadow:0 8px 24px rgba(20,22,30,.14);
}
.home-view .menu-dropdown .menu-contents li a {
  color:var(--dpt-ink); font-family:'IBM Plex Sans',sans-serif;
}
.home-view .menu-dropdown .menu-contents li a:hover { background:var(--dpt-hover-bg); }
.home-view .menu-dropdown .menu-contents li a.danger { background:var(--dpt-err); color:#fff; }
.home-view .menu-dropdown .menu-contents li a.danger:hover { filter:brightness(1.1); }

