/*
 * Putki Web login page — the putki.io house style.
 *
 * This file REPLACES Apache Hop's own login stylesheet inside the hop-ui-rap jar at image
 * build time (see unified.Dockerfile). Hop serves it, unauthenticated, at /login/login.css
 * and looks it up on the classpath as org/apache/hop/ui/hopgui/login/login.css, so the
 * class names below are Hop's and not ours: .shell .card .brand .brand-logo .subtitle
 * .panel .welcome .field .error .actions .btn-primary .footer .badge. Renaming one here
 * styles nothing — the markup is rendered by HopLoginPage.
 *
 * The wording (heading, strapline, welcome) is NOT set here. It comes from
 * HOP_WEB_BRAND_NAME / HOP_WEB_BRAND_TAGLINE / HOP_WEB_WELCOME_MESSAGE, which is the point:
 * patching someone else's rendered HTML is what left this image without Hop's security
 * filters for a release, and text belongs in configuration rather than in a stylesheet.
 *
 * NO WEBFONTS, DELIBERATELY. putki.io sets Fraunces / DM Sans / DM Mono, and the faithful
 * thing would be to @import them. This is the page that renders before anyone has signed
 * in, so an @import would tell Google that a given IP opened a Putki login screen — the
 * same reasoning that strips the Google Fonts link out of putki-tools' HTML reports. The
 * stacks below lead with those families so a machine that already has them looks right,
 * and fall back to system faces everywhere else.
 */

:root {
  /* Lifted from tools/render-security-page.py's HOUSE dict, which is itself taken from
     putki.io's own page CSS. One source for the palette; if the site moves, both move. */
  --putki-bg: #131f35;
  --putki-surface: rgba(255, 255, 255, 0.04);
  --putki-border: rgba(255, 255, 255, 0.07);
  --putki-brand: #1e7fb1;
  --putki-brand-dim: rgba(30, 127, 177, 0.12);
  --putki-pale: #c8e7fa;
  --putki-text: #e9f2f7;
  --putki-muted: rgba(233, 242, 247, 0.5);
  --putki-faint: rgba(233, 242, 247, 0.35);
  --putki-red: #f87171;
  --putki-radius: 14px;

  --putki-sans: "DM Sans", system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial,
    sans-serif;
  --putki-serif: "Fraunces", Georgia, "Times New Roman", serif;
}

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  min-height: 100%;
}

body {
  font-family: var(--putki-sans);
  color: var(--putki-text);
  background: var(--putki-bg);
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  line-height: 1.65;
}

/* Two soft pools of brand light, same trick the site uses to stop a flat navy reading as
   a terminal. Fixed rather than absolute so short viewports do not clip them. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  background:
    radial-gradient(ellipse 80% 50% at 12% 18%, rgba(200, 231, 250, 0.1), transparent 52%),
    radial-gradient(ellipse 60% 44% at 88% 82%, rgba(30, 127, 177, 0.22), transparent 48%);
  pointer-events: none;
}

.shell {
  position: relative;
  width: 100%;
  max-width: 420px;
  z-index: 1;
}

/* Dark card on dark ground, separated by a hairline rather than a shadow — Hop's original
   is a white card, so this is the one rule that most changes the page's character. */
.card {
  background: var(--putki-surface);
  border: 1px solid var(--putki-border);
  border-radius: var(--putki-radius);
  overflow: hidden;
  backdrop-filter: blur(6px);
}

.brand {
  padding: 34px 28px 26px;
  text-align: center;
  border-bottom: 1px solid var(--putki-border);
}

.brand-logo {
  width: 72px;
  height: 72px;
  margin: 0 auto 18px;
  display: block;
  /* The Putki mark is a coloured glyph on transparency, so it needs no plate behind it —
     unlike Hop's, which is drawn to sit on its navy tile. */
  border-radius: 0;
  background: none;
  box-shadow: none;
}

.brand h1 {
  margin: 0 0 6px;
  font-family: var(--putki-serif);
  font-size: 1.6rem;
  font-weight: 800;
  letter-spacing: -0.01em;
  line-height: 1.1;
  color: var(--putki-text);
}

.brand .subtitle {
  margin: 0;
  font-size: 0.92rem;
  color: var(--putki-pale);
  font-weight: 400;
}

/* Hop puts the auth mode here. Treated as the site's eyebrow: small, spaced, uppercase. */
.badge {
  display: inline-block;
  margin-top: 14px;
  padding: 4px 10px;
  border-radius: 999px;
  background: var(--putki-brand-dim);
  border: 1px solid var(--putki-border);
  color: var(--putki-pale);
  font-family: ui-monospace, "DM Mono", SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.panel {
  padding: 26px 28px 22px;
  position: relative;
}

.welcome {
  margin: 0 0 22px;
  color: var(--putki-muted);
  font-size: 0.93rem;
  text-align: center;
}

.field {
  margin-bottom: 16px;
}

.field label {
  display: block;
  font-size: 0.72rem;
  font-weight: 600;
  color: var(--putki-pale);
  margin-bottom: 6px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.field input {
  width: 100%;
  padding: 12px 14px;
  border: 1px solid var(--putki-border);
  border-radius: 10px;
  font-size: 1rem;
  font-family: inherit;
  color: var(--putki-text);
  background: rgba(255, 255, 255, 0.03);
  transition: border-color 0.15s ease, box-shadow 0.15s ease, background 0.15s ease;
}

.field input:focus {
  outline: none;
  border-color: var(--putki-brand);
  box-shadow: 0 0 0 3px var(--putki-brand-dim);
  background: rgba(255, 255, 255, 0.06);
}

.field input::placeholder {
  color: var(--putki-faint);
}

/* Autofill in WebKit repaints the field white with black text, which on a dark card looks
   broken. The long inset shadow is the only way to override it. */
.field input:-webkit-autofill,
.field input:-webkit-autofill:focus {
  -webkit-text-fill-color: var(--putki-text);
  -webkit-box-shadow: 0 0 0 1000px #1b2942 inset;
  caret-color: var(--putki-text);
}

.error {
  background: rgba(248, 113, 113, 0.12);
  color: var(--putki-red);
  border: 1px solid rgba(248, 113, 113, 0.28);
  border-radius: 10px;
  padding: 12px 14px;
  font-size: 0.88rem;
  margin-bottom: 16px;
}

.actions {
  margin-top: 8px;
}

.btn-primary {
  display: block;
  width: 100%;
  border: none;
  border-radius: 10px;
  padding: 13px 16px;
  font-size: 0.98rem;
  font-family: inherit;
  font-weight: 600;
  color: #ffffff;
  background: var(--putki-brand);
  cursor: pointer;
  transition: filter 0.12s ease, transform 0.12s ease;
}

.btn-primary:hover {
  filter: brightness(1.12);
}

.btn-primary:active {
  transform: translateY(1px);
}

.btn-primary:focus-visible {
  outline: 2px solid var(--putki-pale);
  outline-offset: 2px;
}

.footer {
  margin-top: 20px;
  text-align: center;
  font-size: 0.8rem;
  color: var(--putki-faint);
}

.footer a {
  color: var(--putki-pale);
  text-decoration: none;
}

.footer a:hover {
  text-decoration: underline;
}

/*
 * Attribution line: "Putki is a product developed by know.bi".
 *
 * Generated content rather than markup, because HopLoginPage renders the panel and the only
 * hooks it leaves a distributor are this stylesheet and the logo. The trade-off is real —
 * CSS content is not reliably reachable by assistive technology and cannot be selected —
 * which is acceptable for an attribution line and would not be for anything a user has to
 * act on.
 *
 * The know.bi wordmark is set as text rather than as the real logo on purpose. Hop serves
 * exactly two unauthenticated assets, /login/login.css and /login/logo.svg, and the second
 * is taken by the Putki mark; anything else 302s to the login page and renders broken. The
 * only way to show the actual logo here is to inline it, and it is a 130-path illustration
 * that costs ~26 KB base64 to display at 80 px, where none of that detail survives.
 */
.panel::after {
  content: "Putki is a product developed by know.bi";
  display: block;
  margin-top: 6px;
  text-align: center;
  font-size: 0.74rem;
  letter-spacing: 0.01em;
  color: var(--putki-faint);
}

/*
 * Wording, which upstream renders as literals in HopLoginPage and offers no hook for.
 *
 * Replacing text from a stylesheet is not good practice and is done here only because the
 * alternative is worse: rewriting Apache's markup, which is how this image came to be
 * missing Hop's security filters. The cost is that assistive technology still announces
 * the real text ("Apache Hop Web") and a sighted user cannot select what they see. That is
 * tolerable for a product name and would not be for anything carrying meaning — which is
 * why the welcome line, the error text and the button labels are all left alone.
 *
 * The <title> and the logo's alt text stay "Apache Hop Web": neither is reachable from
 * CSS. Making these configurable upstream is the real fix and is worth doing later.
 */
.brand h1 {
  font-size: 0 !important;
  line-height: 0 !important;
}

.brand h1::after {
  content: "Putki Web";
  font-family: var(--putki-serif);
  font-size: 1.6rem;
  font-weight: 800;
  line-height: 1.1;
  letter-spacing: -0.01em;
  color: var(--putki-text);
}

.brand .subtitle {
  font-size: 0 !important;
}

.brand .subtitle::after {
  content: "Powered by Apache Hop";
  font-size: 0.92rem;
  font-weight: 400;
  color: var(--putki-pale);
}

/*
 * Upstream closes the panel with its own "Powered by Apache Hop" line, which the strapline
 * above now says. Two of them on one card reads as a mistake, so the lower one goes.
 *
 * `:last-of-type` rather than a class, because both that line and the OAuth mode's "You
 * will be redirected to your identity provider." carry class="footer" and only the
 * powered-by is last. ::after is generated content and does not count as an element, so
 * the attribution line above does not disturb this.
 */
.panel > p.footer:last-of-type {
  display: none;
}

@media (prefers-reduced-motion: reduce) {
  * {
    transition: none !important;
  }
}
