:root {/* Canonical palette - single source for colour. *//* DARK - 35% */--black:#07080A;--black-2:#0F0F13;--charcoal:#1A1A1F;--graphite:#24252A;/* LIGHT - 40% */--light-bg:#F4F5F4;--light-panel:#FAFAF9;--light-panel-2:#FFFFFF;/* MIST / BRIDGE - 15% */--stone:#5D5F63;--mist:#ADAFB3;--foam:#C9CBCE;--foam-2:#DEE0E2;--dark-bg:#0F0F13;--dark-panel:#1A1A1F;--dark-panel-2:#24252A;--bridge:#ADAFB3;--bridge-soft:#DEE0E2;/* STEEL ACCENT - 10% */--accent-steel:#60788E;--accent-steel-soft:#8FA4B3;--accent-steel-muted:#A9B8C3;--accent-steel-pale:#CBD5DC;--accent-steel-wash:#EDF2F4;/* BLUE AURA */--blue:#60788E;--blue-soft:#91A8BA;--blue-pale:#C3D0DA;--blue-wash:#EDF2F5;/* SEMANTIC */--crit:#D14B4B;--high:var(--accent-steel);--med:#C9B458;--low:#6E9B6B;--ok:#5E8D86;/* TEXT */--text:#1A1A1F;--text-strong:#07080A;--text-secondary:#5D5F63;--text-muted:#7D8185;--text-soft:#ADAFB3;--text-dark:#DEE0E2;--text-dark-secondary:#ADAFB3;/* BORDER */--line-dark:rgba(222,224,226,.12);--line-dark-strong:rgba(222,224,226,.20);--line-light:#D7D9D8;--line-light-soft:#E5E7E6;--line-light-strong:#C9CBCE;--line-accent:rgba(96,120,142,.28);/* INTERACTION */--hover-light:#ECEEED;--active-light:#E3E6E4;--hover-dark:#24252A;--active-dark:#2C2D32;--accent:var(--accent-steel);--accent-hover:#4D657A;--accent-soft:var(--accent-steel-pale);/* GEOMETRY (unchanged: the app's own scale) */--radius:.3rem;--radius-sm:.3rem;/* SHADOW */--shadow:0 16px 44px rgba(7,8,10,.10);--shadow-soft:0 8px 24px rgba(7,8,10,.07);/* TYPOGRAPHY (unchanged: the app's own stacks) */--ff-mono:ui-monospace,"Cascadia Mono","Segoe UI Mono","Liberation Mono",Menlo,Monaco,Consolas,monospace;--ff-sans:-apple-system,BlinkMacSystemFont,"Segoe UI Adjusted","Segoe UI","Liberation Sans",sans-serif;color-scheme:light;/* Legacy aliases: the app's older token names, pointed at the palette above so every existing rule follows it without being rewritten. */--porcelain:var(--light-bg);--paper:var(--light-panel);--soft-steel:var(--foam-2);--steel-gray:var(--stone);--ink:var(--black);--burnt-copper:var(--accent-steel);--burnt-copper-soft:var(--accent-steel-pale);--panel:var(--light-panel);--panel2:var(--light-panel);--panel-soft:var(--light-panel);--panel-raised:var(--light-panel-2);--panel-fade:var(--light-panel);--nav:var(--light-panel);--bg:var(--light-bg);--light:var(--light-bg);--surface:var(--light-bg);--border:var(--line-light);--line:var(--line-light);--line2:var(--line-light-soft);--line-soft:var(--line-light-soft);--stroke:var(--line-light);--btn:var(--graphite);--primary:var(--graphite);--primary2:var(--black);--strong:var(--black);--dark:var(--black);--muted:var(--text-muted);--faded:var(--stone);--accent-h:var(--accent-hover);--accent-s:var(--accent-steel-pale);--on:var(--light-panel-2);--on-accent:var(--light-panel-2);--inverse:var(--light-panel-2);--good:var(--ok);--success:var(--ok);--ok-soft:rgba(94,141,134,.16);--success-soft:rgba(94,141,134,.16);--bad:var(--crit);--danger:var(--crit);--danger-soft:rgba(209,75,75,.14);--warn:var(--med);--blue-line:var(--blue-pale);--shadow-modal:var(--shadow);--font:var(--ff-sans);--pointer-x:50vw;--pointer-y:50vh;--fs-xs:11px;--fs-sm:12px;--fs-base:12px;--fs-md:13px;--fs-lg:15px;--fs-xl:18px;--fw-regular:400;--fw-medium:500;--fw-semibold:600;--fw-bold:700;--lh-tight:1.2;--lh-snug:1.35;--lh-normal:1.5;--lh-relaxed:1.7;--btn-bg:#444746;--btn-fg:#f5f6f3;--btn-border:#444746;/* Kept from the previous block (not part of the palette). */--mono:var(--ff-mono);}

@media (prefers-color-scheme: dark) {
}

* {
    box-sizing: border-box
}

html,body {
    width: 100%;
    height: 100dvh;
    margin: 0;
}

body {
    padding: 42px 8px 18px;
    font-family:var(--ff-sans);
    font-size: var(--fs-base);
    line-height: var(--lh-normal);
    background: radial-gradient(circle at 50% 8%,rgba(7,8,10,.12),transparent 28rem),radial-gradient(circle at 10% 80%,rgba(7,8,10,.06),transparent 22rem),var(--porcelain);
    color: var(--text);
    -webkit-font-smoothing: antialiased;
    text-rendering: geometricPrecision
}

.container {
    width: 100%;
    max-width: 450px!important;
    margin: 0 auto!important
}

.panel,.panel-default {
    margin: 0 auto;
    max-width: 450px;
    border: 0px!important;
    border-radius: var(--radius)!important;
    background: var(--panel)!important;
    overflow: hidden;
    box-shadow: rgba(0, 0, 0, 0.05) 0px 6px 24px 0px, rgba(0, 0, 0, 0.08) 0px 0px 0px 1px !important;
}

.panel-heading {
    padding: 8px 10px;
    background: var(--porcelain)!important;
    border-bottom: 1px solid var(--line-soft)!important;
    color: var(--text-strong);
    font-size: var(--fs-base)
}

.panel-body {
    padding: 10px;
    background: transparent!important
}

.msg {
    margin-bottom: 8px;
    padding: 8px 10px;
    border: 1px solid var(--line-soft);
    background: var(--panel-soft);
    color: var(--muted);
    border-radius: var(--radius);
    font-size: var(--fs-sm);
    font-family:var(--ff-sans)}

/* One flex row for the field, the reveal and the submit wrapper. Flex does two
   jobs: it lets the reveal share the field's line at the phone breakpoint while
   the submit takes the row below (see the media query further down), and it
   sidesteps Bootstrap's `.input-group .form-control{display:table-cell}` — a
   table-cell inside a block .input-group is wrapped in an anonymous, shrink-to-fit
   table, so under the old display:block the field stopped filling the panel and
   the reveal floated away from its right edge.

   width:auto on .input-group-btn undoes Bootstrap's width:1%, which as a flex
   basis would collapse the submit wrapper to 1% of the row. */
.input-group {
    display: flex;
    align-items: stretch;
    width: 100%
}

.input-group>.form-control {
    position: relative;
    z-index: 2;
    flex: 1 1 auto;
    min-width: 0
}

.input-group-btn {
    display: flex;
    flex: 0 0 auto;
    width: auto
}

.form-control {
    height: 31px!important;
    border: 1px solid var(--line)!important;
    border-radius: var(--radius)!important;
    background: var(--panel)!important;
    color: var(--text)!important;
    box-shadow: none!important;
    font-family:var(--ff-sans);
    font-size: var(--fs-sm);
    caret-color: var(--text)!important
}

.form-control:-webkit-autofill,.form-control:-webkit-autofill:focus {
    -webkit-box-shadow: 0 0 0 1000px var(--panel2) inset!important;
    -webkit-text-fill-color: var(--text)!important;
    caret-color: var(--text)!important
}

.form-control::placeholder {
    color: color-mix(in srgb,var(--text) 54%,transparent)
}

.form-control:focus {
    outline: none;
    border-color: #9E9E9E !important;
}

/* Centred by layout, not by a magic offset.
   This button used to be an inline-block whose inline <svg> sat on the text baseline,
   compensated with vertical-align:-2px on the svg itself. Measured against the real
   cascade that left the icon 1.09px above the button's midline (and 1px above the
   label), and the offset is invisible to flex anyway. Making the button the flex
   container centres every child -- including the .btn-spin svg the login script
   injects into it -- and turns the inline gap:6px into a real gap. */
.input-group-btn>.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    min-width: 148px;
    height: 31px;
    border: 1px solid var(--btn-border)!important;
    border-radius: var(--radius)!important;
    background: var(--btn-bg)!important;
    color: var(--btn-fg)!important;
    font-size: var(--fs-sm);
    box-shadow: none!important;
}

.input-group-btn>.btn > svg {
    flex: 0 0 auto;
}

/* The Login submit is the one label in this group, so it is the only element
   here a weight can act on: the reveal control beside it is an icon-only button
   whose child is an <svg> with no text. Scoped to [type=submit] so the eye
   cannot inherit a bolder glyph, and read from the --fw-bold token (700) rather
   than a bare number so it follows the scale if that scale ever moves. */
.input-group-btn>.btn[type=submit] {
    font-weight: var(--fw-bold, 700);
}

.input-group-btn>.btn:hover,.input-group-btn>.btn:focus-visible,.input-group-btn>.btn:active,.input-group-btn>.btn.active {
    background: #444746!important;
    filter: none;
    border-color: #444746!important;
    color: #f5f6f3!important
}

/* Phone layout: one 44px row holding the field with the reveal at its right edge,
   then the submit on its own full-width row below.

   The reveal is a sibling of .input-group-btn, not a member of it. Both buttons
   used to share that wrapper, and once the group stacked they could only both go
   full-width -- the icon-only reveal turned into an empty dark bar wedged between
   the field and Login. As siblings they are ordered instead: field, reveal, then
   the submit wrapper forced onto its own line.

   ui-sync.css loads after this file, so every geometry rule here needs !important
   AND a compound selector. Its `.input-group-btn > .btn` is (0,2,0) and, on a tie,
   would win by source order against a plain `.input-group-btn>.btn` and snap the
   submit back to the 28px desktop height; the `[type=submit]` / `[data-pw-toggle]`
   suffixes lift these to (0,3,0). */
@media screen and (max-width: 560px) {
    /* env() keeps the panel clear of the notch and the home indicator. */
    body {
        /* Spasi atas mengikuti login statistik: 34px + safe-area. Tinggi body
           auto + min-height agar tetap bisa discroll di layar pendek. */
        height: auto;
        min-height: 100dvh;
        padding: calc(34px + env(safe-area-inset-top, 0px)) calc(10px + env(safe-area-inset-right, 0px)) calc(18px + env(safe-area-inset-bottom, 0px)) calc(10px + env(safe-area-inset-left, 0px));
        font-size: var(--fs-base)
    }

    .container,.login-wrap {
        max-width: none;
        margin-top: 0
    }

    .panel-heading,.panel-body {
        padding: 10px 12px
    }

    .msg {
        margin-bottom: 10px;
        padding: 9px 11px;
        line-height: var(--lh-normal)
    }

    .input-group {
        display: flex;
        flex-wrap: wrap;
        align-items: stretch;
        width: 100%
    }

    /* 16px is the smallest size iOS will not zoom the viewport for when the field
       takes focus; flex:1 1 0 with min-width:0 takes the row minus the reveal
       without shrinking below the placeholder. Border-radius is left to ui-sync,
       which flattens inputs: the group is square on the left and rounded on the
       right, as on desktop. */
    .input-group>.form-control {
        flex: 1 1 0;
        width: auto;
        min-width: 0;
        order: 1;
        height: 44px!important;
        padding: 0 12px;
        font-size: 16px!important
    }

    /* order:2 + flex:0 0 44px keeps the reveal on the field's row, at its right
       edge, at the WCAG 2.5.5 touch height. */
    .input-group>.btn[data-pw-toggle] {
        order: 2;
        flex: 0 0 44px;
        width: 44px!important;
        min-width: 44px!important;
        max-width: 44px!important;
        height: 44px!important;
        min-height: 44px!important;
        margin: 0!important;
        border-radius: var(--radius)!important
    }

    .input-group-btn {
        order: 3;
        flex: 1 0 100%;
        width: 100%;
        margin-top: 8px
    }

    .input-group-btn>.btn[type=submit] {
        width: 100%!important;
        min-width: 0!important;
        height: 44px!important;
        min-height: 44px!important;
        margin: 0!important;
        border-radius: var(--radius)!important;
        font-size: var(--fs-sm)
    }
}

::selection {
    background: rgba(7,8,10,.18);
    color: var(--text-strong)
}

:focus-visible {
    outline: 1px solid rgba(7,8,10,.32);
    outline-offset: 1px
}

input:focus,textarea:focus,select:focus,button:focus,.form-control:focus,.btn:focus,a:focus {
    outline: none!important
}

input[type=password]::-ms-reveal,input[type=password]::-ms-clear,input[type=password]::-webkit-textfield-decoration-container {
    display: none!important
}

.login-wrap {
    max-width: 450px;
    margin-top: -10px
}

select hr {
    border: none;
    border-top: 1px solid rgba(36,37,42,.06)!important;
    color: rgba(36,37,42,.06)!important;
    opacity: .45;
    margin: 1px 4px
}

.app-sign {
    text-align: right;
    padding: 3px 0 2px
}

.app-sign footer {
    font-family:var(--ff-sans);
    text-decoration: none;
    letter-spacing: .09em;
    font-size: var(--fs-xs, 11px);
    font-weight: 900;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
    user-select: none;
    text-transform: uppercase;
    -webkit-user-select: none
}

input[type=url] {
    font-family:var(--ff-sans) !important}

.usr {
    font-family:var(--ff-sans)}

@keyframes btn-spin {
    to {
        transform: rotate(360deg)
    }
}

.btn-spin {
    display: inline-block;
    vertical-align: -2px;
    animation: btn-spin .7s linear infinite;
    opacity: .8
}

body::before {
    content: '';
    position: fixed;
    top: 12px;
    left: 14px;
    z-index: 0;
    font:600 11px/1 var(--ff-sans);
    letter-spacing: .24em;
    text-transform: uppercase;
    color: rgba(36,37,42,.06);
    pointer-events: none
}

body::after {
    content: '';
    position: fixed;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    background-image: url('/assets/img/favicon.svg'),url('/assets/img/bg-intro.png');
    background-repeat: no-repeat,no-repeat;
    background-position: right 14px bottom 12px,center center;
    background-size: 28px 28px,cover;
    opacity: .28;
    filter: saturate(.68) contrast(.84) brightness(1.03) blur(.32px);
    transform: translateZ(0)
}

.noise {
    position: fixed;
    z-index: 90;
    inset: 0;
    pointer-events: none;
    opacity: 0.035;
    mix-blend-mode: soft-light;
    background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 180 180' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='.7'/%3E%3C/svg%3E");
}

.scanline {
    position: fixed;
    z-index: -2;
    inset: 0;
    pointer-events: none;
    background-image: linear-gradient(rgba(93,95,99,0.07) 1px, transparent 1px), linear-gradient(90deg, rgba(93,95,99,0.07) 1px, transparent 1px);
    background-size: 44px 44px;
    mask-image: linear-gradient(to bottom, #202426, transparent 92%);
}
