diff --git a/settings-site/public/css/login.css b/settings-site/public/css/login.css index b02ba36..ddba54a 100644 --- a/settings-site/public/css/login.css +++ b/settings-site/public/css/login.css @@ -1,49 +1,179 @@ * { margin: 0; padding: 0; box-sizing: border-box; } + +:root { + --bg: #0D0F13; + --surface: #151920; + --border: #262C35; + --border-strong: #3A4150; + --primary: #C7E94D; + --primary-hover: #B5D83D; + --text: #EFEEE8; + --text-muted: #9CA3AE; + --danger: #FF5A52; + --font-title: 'Sora', system-ui, -apple-system, sans-serif; + --font-body: 'Open Sans', system-ui, -apple-system, sans-serif; +} + body { - font-family: 'Inter', sans-serif; - background: #0f1117; - color: #e0e0e0; + font-family: var(--font-body); + background: var(--bg); + color: var(--text); display: flex; align-items: center; justify-content: center; min-height: 100vh; + position: relative; + overflow: hidden; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; } + +/* Atmospheric glow — two diffused lime pools for depth */ +body::before, +body::after { + content: ''; + position: absolute; + border-radius: 50%; + pointer-events: none; + filter: blur(70px); +} +body::before { + width: 640px; + height: 640px; + top: -220px; + left: -200px; + background: radial-gradient(circle, rgba(199, 233, 77, 0.10), transparent 60%); +} +body::after { + width: 420px; + height: 420px; + bottom: -160px; + right: -140px; + background: radial-gradient(circle, rgba(199, 233, 77, 0.06), transparent 60%); +} + +/* Grid texture overlay — subtle but sets the tone */ +body { + background-image: + linear-gradient(rgba(199, 233, 77, 0.025) 1px, transparent 1px), + linear-gradient(90deg, rgba(199, 233, 77, 0.025) 1px, transparent 1px); + background-size: 40px 40px; + background-position: center center; +} + .login-card { - background: #1e2235; - border: 1px solid #2a2d3e; - border-radius: 16px; - padding: 48px 40px; - width: 380px; - text-align: center; - box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4); + position: relative; + z-index: 1; + background: var(--surface); + border: 1px solid var(--border); + border-top: 3px solid var(--primary); + padding: 44px 40px 40px; + width: 400px; + box-shadow: 0 24px 80px rgba(0, 0, 0, 0.5); } -.login-card h1 { font-size: 22px; font-weight: 700; margin-bottom: 8px; } -.login-card p { font-size: 14px; color: #888; margin-bottom: 32px; } + +/* Tag above title */ +.login-card::before { + content: 'RESTRICTED'; + display: block; + font-family: var(--font-title); + font-size: 10px; + font-weight: 700; + letter-spacing: 0.32em; + color: var(--primary); + margin-bottom: 14px; +} + +.login-card h1 { + font-family: var(--font-title); + font-size: 16px; + font-weight: 700; + letter-spacing: 0.18em; + text-transform: uppercase; + margin-bottom: 10px; + line-height: 1.3; +} +.login-card h1::after { + content: ' (:|)'; + color: var(--primary); + font-weight: 500; + letter-spacing: 0; + margin-left: 2px; +} + +.login-card p { + font-size: 13px; + color: var(--text-muted); + margin-bottom: 30px; + line-height: 1.55; +} + .login-card input { width: 100%; - padding: 12px 16px; - background: #0f1117; - border: 1px solid #2a2d3e; - border-radius: 8px; - color: #e0e0e0; + padding: 13px 14px; + background: var(--bg); + border: 1px solid var(--border); + color: var(--text); + font-family: var(--font-body); font-size: 14px; - margin-bottom: 16px; + margin-bottom: 14px; outline: none; - transition: border-color 200ms; + transition: border-color 180ms ease, box-shadow 180ms ease; } -.login-card input:focus { border-color: #5865f2; } +.login-card input::placeholder { color: #6B7280; } +.login-card input:focus { + border-color: var(--primary); + box-shadow: 0 0 0 3px rgba(199, 233, 77, 0.15); +} + .login-card button { width: 100%; - padding: 12px; - background: #5865f2; - color: #fff; - border: none; - border-radius: 8px; - font-size: 14px; - font-weight: 600; + padding: 13px 16px; + background: var(--primary); + color: var(--bg); + border: 1px solid var(--primary); + font-family: var(--font-title); + font-size: 11px; + font-weight: 700; + letter-spacing: 0.2em; + text-transform: uppercase; cursor: pointer; - transition: background 200ms; + transition: background 180ms ease, border-color 180ms ease; + margin-top: 4px; +} +.login-card button:hover { + background: var(--primary-hover); + border-color: var(--primary-hover); +} +.login-card button:focus-visible { + outline: 2px solid var(--text); + outline-offset: 2px; +} + +.error { + color: var(--danger); + font-family: var(--font-title); + font-size: 11px; + font-weight: 600; + letter-spacing: 0.12em; + text-transform: uppercase; + margin-top: 12px; + display: none; } -.login-card button:hover { background: #4752c4; } -.error { color: #ed4245; font-size: 13px; margin-top: 8px; display: none; } .error.visible { display: block; } + +/* Bottom watermark */ +.login-card::after { + content: 'indifferent broccoli · internal'; + display: block; + margin-top: 32px; + padding-top: 20px; + border-top: 1px solid var(--border); + font-family: var(--font-title); + font-size: 10px; + font-weight: 500; + letter-spacing: 0.3em; + color: #6B7280; + text-transform: uppercase; + text-align: center; +} diff --git a/settings-site/public/css/main.css b/settings-site/public/css/main.css index 4a3c033..851ba8c 100644 --- a/settings-site/public/css/main.css +++ b/settings-site/public/css/main.css @@ -1,157 +1,893 @@ -@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap'); +@import url('https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;500;600;700&family=Sora:wght@400;500;600;700;800&display=swap'); * { margin: 0; padding: 0; box-sizing: border-box; } :root { - --bg: #0f1117; - --surface: #1a1d27; - --card: #1e2235; - --border: #2a2d3e; - --accent: #5865f2; - --accent-hover: #4752c4; - --success: #57f287; - --warning: #fee75c; - --danger: #ed4245; - --text: #e0e0e0; - --text-muted: #888; + /* Palette — "indifferent broccoli": deep near-black + chartreuse primary */ + --bg: #0D0F13; + --surface: #151920; + --surface-2: #1E242C; + --card: #151920; + --border: #262C35; + --border-strong: #3A4150; + + --primary: #C7E94D; + --primary-hover: #B5D83D; + --primary-dim: rgba(199, 233, 77, 0.12); + --primary-dim-2: rgba(199, 233, 77, 0.06); + + --secondary: #FFB84D; + --danger: #FF5A52; + --warning: #FFD66B; + --success: #7EE0A3; + + --text: #EFEEE8; + --text-muted: #9CA3AE; + --text-dim: #6B7280; + --sidebar-width: 260px; + --topbar-height: 60px; + + --font-title: 'Sora', system-ui, -apple-system, sans-serif; + --font-body: 'Open Sans', system-ui, -apple-system, sans-serif; + --font-mono: ui-monospace, 'SF Mono', 'JetBrains Mono', Menlo, monospace; } -body { font-family: 'Inter', sans-serif; background: var(--bg); color: var(--text); display: flex; min-height: 100vh; } +body { + font-family: var(--font-body); + background: var(--bg); + color: var(--text); + display: flex; + min-height: 100vh; + font-size: 14px; + line-height: 1.5; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +/* Ambient atmospheric glow — a single diffused lime pool, top-left */ +body::before { + content: ''; + position: fixed; + top: -200px; + left: -100px; + width: 640px; + height: 640px; + background: radial-gradient(circle, rgba(199, 233, 77, 0.08), transparent 60%); + filter: blur(60px); + pointer-events: none; + z-index: 0; +} /* Top bar */ -.topbar { position: fixed; top: 0; left: var(--sidebar-width); right: 0; height: 56px; background: var(--surface); border-bottom: 1px solid var(--border); display: flex; align-items: center; justify-content: space-between; padding: 0 24px; z-index: 100; } -.topbar h1 { font-size: 16px; font-weight: 600; } -.topbar .status { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--text-muted); } -.topbar .status .dot { width: 8px; height: 8px; border-radius: 50%; } -.topbar .status .dot.online { background: var(--success); } +.topbar { + position: fixed; + top: 0; + left: var(--sidebar-width); + right: 0; + height: var(--topbar-height); + background: var(--surface); + border-bottom: 1px solid var(--border); + display: flex; + align-items: center; + justify-content: space-between; + padding: 0 24px; + z-index: 100; + gap: 16px; +} +.topbar h1 { + font-family: var(--font-title); + font-size: 13px; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.18em; + color: var(--text); +} +.topbar h1::after { + content: ' (:|)'; + color: var(--primary); + margin-left: 2px; + letter-spacing: 0; + font-weight: 500; +} +.topbar .status { + display: flex; + align-items: center; + gap: 10px; + font-family: var(--font-title); + font-size: 11px; + font-weight: 600; + color: var(--text-muted); + text-transform: uppercase; + letter-spacing: 0.14em; +} +.topbar .status .dot { width: 8px; height: 8px; border-radius: 0; flex-shrink: 0; } +.topbar .status .dot.online { background: var(--primary); box-shadow: 0 0 14px var(--primary-dim); } .topbar .status .dot.offline { background: var(--danger); } -.topbar .actions { display: flex; gap: 12px; align-items: center; } -.topbar .actions button { background: none; border: 1px solid var(--border); color: var(--text-muted); padding: 6px 14px; border-radius: 6px; font-size: 13px; cursor: pointer; transition: all 200ms; } -.topbar .actions button:hover { border-color: var(--accent); color: var(--text); } +.topbar .actions { display: flex; gap: 10px; align-items: center; } +.topbar .actions button { + background: transparent; + border: 1px solid var(--border-strong); + color: var(--text); + padding: 8px 16px; + font-family: var(--font-title); + font-size: 11px; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.14em; + cursor: pointer; + transition: border-color 180ms ease, color 180ms ease, background 180ms ease; +} +.topbar .actions button:hover { + border-color: var(--primary); + color: var(--primary); + background: var(--primary-dim-2); +} /* Sidebar */ -.sidebar { position: fixed; top: 0; left: 0; width: var(--sidebar-width); height: 100vh; background: var(--surface); border-right: 1px solid var(--border); padding: 16px 0; overflow-y: auto; z-index: 101; } -.sidebar .logo { padding: 12px 20px 24px; font-size: 18px; font-weight: 700; } -.sidebar a { display: flex; align-items: center; gap: 10px; padding: 10px 20px; color: var(--text-muted); text-decoration: none; font-size: 13px; font-weight: 500; border-left: 3px solid transparent; transition: all 200ms; } -.sidebar a:hover { color: var(--text); background: rgba(88,101,242,0.08); } -.sidebar a.active { color: var(--accent); border-left-color: var(--accent); background: rgba(88,101,242,0.1); } +.sidebar { + position: fixed; + top: 0; + left: 0; + width: var(--sidebar-width); + height: 100vh; + background: var(--surface); + border-right: 1px solid var(--border); + padding: 20px 0 24px; + overflow-y: auto; + z-index: 101; +} +.sidebar .logo { + padding: 8px 20px 24px; + font-family: var(--font-title); + font-size: 13px; + font-weight: 700; + letter-spacing: 0.16em; + text-transform: uppercase; + color: var(--text); + line-height: 1.3; + position: relative; +} +.sidebar .logo::after { + content: '(:|)'; + display: block; + margin-top: 4px; + font-size: 11px; + letter-spacing: 0; + color: var(--primary); + font-weight: 500; +} +.sidebar a { + display: flex; + align-items: center; + padding: 11px 20px; + color: var(--text-muted); + text-decoration: none; + font-family: var(--font-title); + font-size: 11px; + font-weight: 600; + letter-spacing: 0.12em; + text-transform: uppercase; + border-left: 3px solid transparent; + transition: color 160ms ease, background 160ms ease, border-color 160ms ease; +} +.sidebar a:hover { + color: var(--text); + background: var(--primary-dim-2); +} +.sidebar a.active { + color: var(--primary); + border-left-color: var(--primary); + background: var(--primary-dim-2); +} -/* Main */ -.main { margin-left: var(--sidebar-width); margin-top: 56px; padding: 24px; flex: 1; padding-bottom: 100px; } +/* Main content */ +.main { + margin-left: var(--sidebar-width); + margin-top: var(--topbar-height); + padding: 32px; + flex: 1; + padding-bottom: 140px; + position: relative; + z-index: 1; +} -/* Section cards */ -.section { margin-bottom: 24px; } -.section-header { background: var(--card); border: 1px solid var(--border); border-radius: 12px 12px 0 0; padding: 20px 24px; cursor: pointer; display: flex; align-items: center; gap: 12px; transition: background 200ms; } -.section-header:hover { background: #232740; } -.section-header h2 { font-size: 15px; font-weight: 600; flex: 1; } -.section-header p { font-size: 12px; color: var(--text-muted); } -.section-header .chevron { transition: transform 200ms; font-size: 18px; color: var(--text-muted); } -.section.collapsed .section-header { border-radius: 12px; } +/* Sections */ +.section { margin-bottom: 20px; } +.section-header { + background: var(--surface); + border: 1px solid var(--border); + border-bottom: none; + padding: 18px 22px; + cursor: pointer; + display: flex; + align-items: center; + gap: 14px; + transition: background 180ms ease, border-color 180ms ease; +} +.section-header:hover { + background: var(--surface-2); + border-color: var(--border-strong); +} +.section-header h2 { + font-family: var(--font-title); + font-size: 14px; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.12em; + color: var(--text); + flex: 1; + display: flex; + align-items: center; + gap: 12px; +} +.section-header h2::before { + content: ''; + display: inline-block; + width: 6px; + height: 6px; + background: var(--primary); + flex-shrink: 0; +} +.section-header p { + font-family: var(--font-body); + font-size: 12px; + font-weight: 400; + color: var(--text-muted); + text-transform: none; + letter-spacing: 0; + line-height: 1.4; +} +.section-header .chevron { + transition: transform 200ms ease; + font-size: 12px; + color: var(--primary); +} +.section.collapsed .section-header { border-bottom: 1px solid var(--border); } .section.collapsed .section-body { display: none; } .section.collapsed .chevron { transform: rotate(-90deg); } -.section-body { background: var(--card); border: 1px solid var(--border); border-top: none; border-radius: 0 0 12px 12px; padding: 24px; } +.section-body { + background: var(--surface); + border: 1px solid var(--border); + padding: 28px 24px; +} /* Field grid */ -.field-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 16px; } -.field { display: flex; flex-direction: column; gap: 6px; } +.field-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); + gap: 22px; +} +.field { display: flex; flex-direction: column; gap: 8px; } .field.full-width { grid-column: 1 / -1; } -.field label { font-size: 12px; font-weight: 600; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.5px; } -.field input, .field select, .field textarea { background: var(--bg); border: 1px solid var(--border); border-radius: 8px; padding: 10px 14px; color: var(--text); font-size: 14px; font-family: inherit; outline: none; transition: border-color 200ms; } -.field input:focus, .field select:focus, .field textarea:focus { border-color: var(--accent); box-shadow: 0 0 0 2px rgba(88,101,242,0.2); } -.field textarea { min-height: 80px; resize: vertical; } -.field input.changed, .field select.changed, .field textarea.changed { border-color: var(--warning); } -.field .hint { font-size: 11px; color: var(--text-muted); } +.field label { + font-family: var(--font-title); + font-size: 10px; + font-weight: 700; + color: var(--text-muted); + text-transform: uppercase; + letter-spacing: 0.16em; +} +.field input, +.field select, +.field textarea { + background: var(--bg); + border: 1px solid var(--border); + border-radius: 2px; + padding: 11px 14px; + color: var(--text); + font-family: var(--font-body); + font-size: 14px; + outline: none; + transition: border-color 180ms ease, box-shadow 180ms ease; +} +.field input::placeholder, +.field textarea::placeholder { color: var(--text-dim); } +.field input:focus, +.field select:focus, +.field textarea:focus { + border-color: var(--primary); + box-shadow: 0 0 0 3px var(--primary-dim-2); +} +.field textarea { + min-height: 88px; + resize: vertical; + line-height: 1.55; +} +.field input.changed, +.field select.changed, +.field textarea.changed { + border-color: var(--warning); + box-shadow: 0 0 0 3px rgba(255, 214, 107, 0.1); +} +.field .hint { + font-size: 12px; + color: var(--text-muted); + font-style: italic; + line-height: 1.4; +} /* Toggle switch */ .toggle-wrap { display: flex; align-items: center; gap: 12px; } -.toggle { position: relative; width: 44px; height: 24px; } +.toggle-wrap > span { + font-family: var(--font-title); + font-size: 10px; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.14em; + color: var(--text-muted); +} +.toggle { position: relative; width: 44px; height: 22px; } .toggle input { opacity: 0; width: 0; height: 0; } -.toggle .slider { position: absolute; inset: 0; background: var(--border); border-radius: 12px; cursor: pointer; transition: background 200ms; } -.toggle .slider::before { content: ''; position: absolute; left: 3px; top: 3px; width: 18px; height: 18px; background: #fff; border-radius: 50%; transition: transform 200ms; } -.toggle input:checked + .slider { background: var(--accent); } -.toggle input:checked + .slider::before { transform: translateX(20px); } +.toggle .slider { + position: absolute; + inset: 0; + background: var(--surface-2); + border: 1px solid var(--border-strong); + cursor: pointer; + transition: background 180ms ease, border-color 180ms ease; +} +.toggle .slider::before { + content: ''; + position: absolute; + left: 3px; + top: 3px; + width: 14px; + height: 14px; + background: var(--text-muted); + transition: transform 200ms ease, background 180ms ease; +} +.toggle input:checked + .slider { + border-color: var(--primary); + background: var(--primary-dim); +} +.toggle input:checked + .slider::before { + transform: translateX(20px); + background: var(--primary); +} /* Color picker */ -.color-field { display: flex; align-items: center; gap: 10px; } -.color-field input[type="color"] { width: 40px; height: 40px; border: 1px solid var(--border); border-radius: 8px; cursor: pointer; background: none; padding: 2px; } +.color-field { display: flex; align-items: center; gap: 12px; } +.color-field input[type="color"] { + width: 44px; + height: 44px; + border: 1px solid var(--border); + cursor: pointer; + background: var(--bg); + padding: 3px; + border-radius: 0; +} +.color-field span { + font-family: var(--font-body); + color: var(--text-muted); + font-size: 13px; +} /* Smart select */ .smart-select { position: relative; } -.smart-select-display { background: var(--bg); border: 1px solid var(--border); border-radius: 8px; padding: 10px 14px; cursor: pointer; display: flex; align-items: center; gap: 8px; min-height: 42px; transition: border-color 200ms; } -.smart-select-display:hover { border-color: var(--accent); } -.smart-select-dropdown { position: absolute; top: 100%; left: 0; right: 0; background: var(--card); border: 1px solid var(--border); border-radius: 10px; margin-top: 4px; z-index: 200; box-shadow: 0 8px 24px rgba(0,0,0,0.5); max-height: 300px; overflow: hidden; display: flex; flex-direction: column; } +.smart-select-display { + background: var(--bg); + border: 1px solid var(--border); + border-radius: 2px; + padding: 11px 14px; + cursor: pointer; + display: flex; + align-items: center; + gap: 10px; + min-height: 44px; + transition: border-color 180ms ease; + font-size: 14px; +} +.smart-select-display:hover { border-color: var(--primary); } +.smart-select-dropdown { + position: absolute; + top: 100%; + left: 0; + right: 0; + background: var(--surface); + border: 1px solid var(--border-strong); + margin-top: 4px; + z-index: 200; + box-shadow: 0 16px 48px rgba(0, 0, 0, 0.55); + max-height: 320px; + overflow: hidden; + display: flex; + flex-direction: column; +} .smart-select-dropdown.hidden { display: none; } -.ss-search { background: var(--bg); border: none; border-bottom: 1px solid var(--border); padding: 10px 14px; color: var(--text); font-size: 13px; outline: none; } -.ss-list { overflow-y: auto; max-height: 250px; padding: 4px; } -.ss-option { padding: 8px 12px; border-radius: 6px; cursor: pointer; display: flex; align-items: center; gap: 8px; font-size: 13px; transition: background 200ms; } -.ss-option:hover { background: rgba(88,101,242,0.15); } -.ss-option.selected { background: rgba(88,101,242,0.2); } +.ss-search { + background: var(--bg); + border: none; + border-bottom: 1px solid var(--border); + padding: 12px 14px; + color: var(--text); + font-family: var(--font-body); + font-size: 13px; + outline: none; +} +.ss-list { + overflow-y: auto; + max-height: 260px; + padding: 4px; +} +.ss-option { + padding: 10px 12px; + cursor: pointer; + display: flex; + align-items: center; + gap: 10px; + font-size: 13px; + transition: background 120ms ease, color 120ms ease; +} +.ss-option:hover { background: var(--primary-dim-2); color: var(--primary); } +.ss-option.selected { background: var(--primary-dim); color: var(--primary); } .ss-option.ss-clear { color: var(--text-muted); font-style: italic; } .ss-label { flex: 1; } .ss-sub { font-size: 11px; color: var(--text-muted); } -.ss-id { font-size: 11px; color: var(--text-muted); font-family: monospace; } -.ss-placeholder { color: var(--text-muted); } +.ss-id { font-size: 11px; color: var(--text-dim); font-family: var(--font-mono); } +.ss-placeholder { color: var(--text-dim); } .ss-avatar { width: 20px; height: 20px; border-radius: 50%; } -.ss-dot { width: 12px; height: 12px; border-radius: 50%; flex-shrink: 0; } +.ss-dot { width: 10px; height: 10px; border-radius: 0; flex-shrink: 0; } /* Save bar */ -.save-bar { position: fixed; bottom: 0; left: var(--sidebar-width); right: 0; background: var(--surface); border-top: 1px solid var(--border); padding: 12px 24px; display: flex; align-items: center; justify-content: space-between; transform: translateY(100%); transition: transform 300ms ease; z-index: 100; } +.save-bar { + position: fixed; + bottom: 0; + left: var(--sidebar-width); + right: 0; + background: var(--surface); + border-top: 2px solid var(--primary); + padding: 16px 24px; + display: flex; + align-items: center; + justify-content: space-between; + transform: translateY(100%); + transition: transform 320ms cubic-bezier(0.4, 0, 0.2, 1); + z-index: 100; + box-shadow: 0 -16px 40px rgba(0, 0, 0, 0.35); + gap: 16px; +} .save-bar.visible { transform: translateY(0); } -.save-bar span { font-size: 13px; color: var(--warning); font-weight: 500; } -.save-actions { display: flex; gap: 8px; } -.save-actions button { padding: 8px 16px; border-radius: 6px; font-size: 13px; font-weight: 600; cursor: pointer; border: none; transition: all 200ms; } -.save-actions button:first-child { background: var(--accent); color: #fff; } -.save-actions button:first-child:hover { background: var(--accent-hover); } -.save-actions button.secondary { background: var(--card); color: var(--text); border: 1px solid var(--border); } -.save-actions button.secondary:hover { border-color: var(--accent); } -.save-actions button.danger { background: var(--danger); color: #fff; } -.save-actions button.danger:hover { background: #c9363a; } +.save-bar > span { + font-family: var(--font-title); + font-size: 11px; + font-weight: 700; + color: var(--warning); + text-transform: uppercase; + letter-spacing: 0.16em; + display: inline-flex; + align-items: center; + gap: 10px; +} +.save-bar > span::before { + content: ''; + width: 7px; + height: 7px; + background: var(--warning); + animation: pulse 1.6s ease-in-out infinite; +} +@keyframes pulse { + 0%, 100% { opacity: 1; transform: scale(1); } + 50% { opacity: 0.3; transform: scale(0.8); } +} +.save-actions { display: flex; gap: 10px; flex-wrap: wrap; } +.save-actions button { + padding: 11px 22px; + font-family: var(--font-title); + font-size: 11px; + font-weight: 700; + letter-spacing: 0.16em; + text-transform: uppercase; + cursor: pointer; + border: 1px solid transparent; + border-radius: 0; + transition: all 180ms ease; +} +.save-actions button:first-child { + background: var(--primary); + color: var(--bg); + border-color: var(--primary); +} +.save-actions button:first-child:hover { + background: var(--primary-hover); + border-color: var(--primary-hover); +} +.save-actions button.secondary { + background: transparent; + color: var(--text); + border-color: var(--border-strong); +} +.save-actions button.secondary:hover { + border-color: var(--primary); + color: var(--primary); +} +.save-actions button.danger { + background: transparent; + color: var(--danger); + border-color: var(--danger); +} +.save-actions button.danger:hover { + background: var(--danger); + color: var(--bg); +} +.save-actions button:disabled { opacity: 0.4; cursor: not-allowed; } /* Toast */ -#toast-container { position: fixed; top: 72px; right: 24px; z-index: 300; display: flex; flex-direction: column; gap: 8px; } -.toast { padding: 12px 20px; border-radius: 8px; font-size: 13px; font-weight: 500; animation: toast-in 300ms ease; } -.toast-success { background: rgba(87,242,135,0.15); color: var(--success); border: 1px solid rgba(87,242,135,0.3); } -.toast-warning { background: rgba(254,231,92,0.15); color: var(--warning); border: 1px solid rgba(254,231,92,0.3); } -.toast-error { background: rgba(237,66,69,0.15); color: var(--danger); border: 1px solid rgba(237,66,69,0.3); } -@keyframes toast-in { from { opacity: 0; transform: translateX(20px); } to { opacity: 1; transform: translateX(0); } } +#toast-container { + position: fixed; + top: 76px; + right: 24px; + z-index: 300; + display: flex; + flex-direction: column; + gap: 8px; + pointer-events: none; +} +.toast { + padding: 12px 18px; + font-family: var(--font-title); + font-size: 11px; + font-weight: 700; + letter-spacing: 0.12em; + text-transform: uppercase; + border-left: 3px solid currentColor; + background: var(--surface); + animation: toast-in 260ms ease; + pointer-events: auto; + max-width: 420px; +} +.toast-success { color: var(--primary); background: rgba(199, 233, 77, 0.06); } +.toast-warning { color: var(--warning); background: rgba(255, 214, 107, 0.08); } +.toast-error { color: var(--danger); background: rgba(255, 90, 82, 0.08); } +@keyframes toast-in { + from { opacity: 0; transform: translateX(20px); } + to { opacity: 1; transform: translateX(0); } +} /* Modal */ -.modal { position: fixed; inset: 0; background: rgba(0,0,0,0.6); display: flex; align-items: center; justify-content: center; z-index: 400; } +.modal { + position: fixed; + inset: 0; + background: rgba(0, 0, 0, 0.72); + backdrop-filter: blur(4px); + -webkit-backdrop-filter: blur(4px); + display: flex; + align-items: center; + justify-content: center; + z-index: 400; +} .modal.hidden { display: none; } -.modal-card { background: var(--card); border: 1px solid var(--border); border-radius: 12px; padding: 24px; min-width: 340px; } -.modal-card h3 { margin-bottom: 16px; font-size: 16px; } -.modal-card input { width: 100%; padding: 10px 14px; background: var(--bg); border: 1px solid var(--border); border-radius: 8px; color: var(--text); font-size: 14px; margin-bottom: 16px; } +.modal-card { + background: var(--surface); + border: 1px solid var(--border); + border-top: 3px solid var(--primary); + padding: 28px; + min-width: 360px; +} +.modal-card h3 { + margin-bottom: 20px; + font-family: var(--font-title); + font-size: 13px; + font-weight: 700; + letter-spacing: 0.16em; + text-transform: uppercase; +} +.modal-card input { + width: 100%; + padding: 11px 14px; + background: var(--bg); + border: 1px solid var(--border); + color: var(--text); + font-family: var(--font-body); + font-size: 14px; + margin-bottom: 20px; + outline: none; + transition: border-color 180ms ease; +} +.modal-card input:focus { border-color: var(--primary); } .modal-actions { display: flex; gap: 8px; justify-content: flex-end; } -.modal-actions button { padding: 8px 16px; border-radius: 6px; font-size: 13px; font-weight: 600; cursor: pointer; border: none; } -.modal-actions button:first-child { background: var(--accent); color: #fff; } -.modal-actions button.secondary { background: var(--card); color: var(--text); border: 1px solid var(--border); } +.modal-actions button { + padding: 10px 20px; + font-family: var(--font-title); + font-size: 11px; + font-weight: 700; + letter-spacing: 0.14em; + text-transform: uppercase; + cursor: pointer; + border: 1px solid transparent; +} +.modal-actions button:first-child { + background: var(--primary); + color: var(--bg); + border-color: var(--primary); +} +.modal-actions button:first-child:hover { background: var(--primary-hover); } +.modal-actions button.secondary { + background: transparent; + color: var(--text); + border-color: var(--border-strong); +} +.modal-actions button.secondary:hover { border-color: var(--primary); color: var(--primary); } /* Loading */ -.loading { position: fixed; inset: 0; background: var(--bg); display: flex; align-items: center; justify-content: center; z-index: 500; } +.loading { + position: fixed; + inset: 0; + background: var(--bg); + display: flex; + flex-direction: column; + gap: 20px; + align-items: center; + justify-content: center; + z-index: 500; +} .loading.hidden { display: none; } -.spinner { width: 40px; height: 40px; border: 3px solid var(--border); border-top-color: var(--accent); border-radius: 50%; animation: spin 0.8s linear infinite; } +.loading::after { + content: 'LOADING (:|)'; + font-family: var(--font-title); + font-size: 11px; + font-weight: 700; + letter-spacing: 0.32em; + color: var(--primary); +} +.spinner { + width: 40px; + height: 40px; + border: 2px solid var(--border); + border-top-color: var(--primary); + border-radius: 0; + animation: spin 0.9s linear infinite; +} @keyframes spin { to { transform: rotate(360deg); } } /* Notifications section */ -#s-notifications .notif-tabs { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 16px; } -#s-notifications .notif-tab-btn { border: 1px solid var(--border); background: var(--surface); color: var(--text); border-radius: 8px; padding: 8px 12px; cursor: pointer; } -#s-notifications .notif-tab-btn.active { border-color: var(--accent); color: var(--accent); } +#s-notifications .notif-tabs { + display: flex; + gap: 4px; + flex-wrap: wrap; + margin-bottom: 22px; + border-bottom: 1px solid var(--border); +} +#s-notifications .notif-tab-btn { + border: none; + background: transparent; + color: var(--text-muted); + font-family: var(--font-title); + font-size: 11px; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.14em; + padding: 10px 16px; + cursor: pointer; + border-bottom: 2px solid transparent; + margin-bottom: -1px; + transition: color 160ms ease, border-color 160ms ease; +} +#s-notifications .notif-tab-btn:hover { color: var(--text); } +#s-notifications .notif-tab-btn.active { color: var(--primary); border-bottom-color: var(--primary); } #s-notifications .notif-panel.hidden { display: none; } -#s-notifications .notif-editor { border: 1px solid var(--border); border-radius: 10px; padding: 14px; margin-bottom: 14px; background: var(--surface); } -#s-notifications .notif-chips { display: flex; gap: 8px; flex-wrap: wrap; margin: 10px 0; min-height: 28px; } -#s-notifications .notif-chip { display: inline-flex; align-items: center; gap: 8px; border: 1px solid var(--border); background: var(--bg); border-radius: 999px; padding: 4px 10px; font-size: 12px; } -#s-notifications .notif-chip button { border: none; background: transparent; color: var(--text-muted); cursor: pointer; padding: 0; line-height: 1; font-size: 14px; } -#s-notifications .notif-input-row { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; } +#s-notifications .notif-editor { + border: 1px solid var(--border); + padding: 20px; + margin-bottom: 16px; + background: var(--surface-2); +} +#s-notifications .notif-chips { + display: flex; + gap: 8px; + flex-wrap: wrap; + margin: 14px 0; + min-height: 32px; +} +#s-notifications .notif-chip { + display: inline-flex; + align-items: center; + gap: 10px; + border: 1px solid var(--primary); + background: var(--primary-dim); + color: var(--primary); + padding: 5px 12px; + font-family: var(--font-title); + font-size: 11px; + font-weight: 700; + letter-spacing: 0.08em; + text-transform: uppercase; +} +#s-notifications .notif-chip button { + border: none; + background: transparent; + color: currentColor; + cursor: pointer; + padding: 0; + line-height: 1; + font-size: 14px; + opacity: 0.6; +} +#s-notifications .notif-chip button:hover { opacity: 1; } +#s-notifications .notif-input-row { + display: flex; + gap: 8px; + flex-wrap: wrap; + align-items: center; +} #s-notifications .notif-input-row input { width: 220px; } -#s-notifications .notif-presets { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 10px; } -#s-notifications .notif-presets button { padding: 6px 10px; border-radius: 8px; border: 1px solid var(--border); background: var(--bg); color: var(--text); cursor: pointer; } -#s-notifications .notif-trigger { margin-top: 10px; } -#s-notifications .notif-trigger summary { cursor: pointer; color: var(--text-muted); font-weight: 600; margin-bottom: 10px; } +#s-notifications .notif-presets { + display: flex; + gap: 6px; + flex-wrap: wrap; + margin-top: 14px; +} +#s-notifications .notif-presets button, +#s-notifications .notif-add-btn { + padding: 8px 14px; + border: 1px solid var(--border-strong); + background: transparent; + color: var(--text-muted); + font-family: var(--font-title); + font-size: 11px; + font-weight: 600; + letter-spacing: 0.12em; + text-transform: uppercase; + cursor: pointer; + transition: border-color 160ms ease, color 160ms ease, background 160ms ease; +} +#s-notifications .notif-presets button:hover, +#s-notifications .notif-add-btn:hover { + border-color: var(--primary); + color: var(--primary); + background: var(--primary-dim-2); +} +#s-notifications .notif-trigger { margin-top: 16px; } +#s-notifications .notif-trigger summary { + cursor: pointer; + color: var(--text-muted); + font-family: var(--font-title); + font-size: 11px; + font-weight: 700; + letter-spacing: 0.16em; + text-transform: uppercase; + margin-bottom: 14px; + user-select: none; + list-style: none; + display: inline-flex; + align-items: center; + gap: 8px; +} +#s-notifications .notif-trigger summary::-webkit-details-marker { display: none; } +#s-notifications .notif-trigger summary::before { + content: '+'; + color: var(--primary); + font-weight: 700; + font-size: 14px; +} +#s-notifications .notif-trigger[open] summary::before { content: '−'; } +#s-notifications .notif-trigger[open] summary { color: var(--primary); } -/* Logging section cross-link hint */ +/* Logging hint link */ .logging-hint { color: var(--text-muted); font-size: 13px; } -.logging-hint a { color: var(--accent); } +.logging-hint a { + color: var(--primary); + text-decoration: underline; + text-decoration-style: wavy; + text-decoration-thickness: 1.5px; + text-underline-offset: 4px; +} +.logging-hint a:hover { color: var(--primary-hover); } -/* Logout form inline layout */ +/* Legacy logout form wrapper (kept for compatibility) */ .logout-form { display: inline; } + +/* Select element styling (native appearance override) */ +.field select { + appearance: none; + -webkit-appearance: none; + background-image: linear-gradient(45deg, transparent 50%, var(--primary) 50%), + linear-gradient(135deg, var(--primary) 50%, transparent 50%); + background-position: calc(100% - 18px) center, calc(100% - 13px) center; + background-size: 5px 5px, 5px 5px; + background-repeat: no-repeat; + padding-right: 36px; +} + +/* ---------- Mobile navigation primitives ---------- */ +.menu-toggle { + display: none; + align-items: center; + justify-content: center; + width: 44px; + height: 44px; + padding: 0; + margin-right: 4px; + background: transparent; + border: 1px solid var(--border-strong); + border-radius: 0; + color: var(--text); + cursor: pointer; + transition: border-color 180ms ease, color 180ms ease, background 180ms ease; +} +.menu-toggle:hover { border-color: var(--primary); color: var(--primary); background: var(--primary-dim-2); } +.menu-toggle:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; } +.menu-toggle-bars, +.menu-toggle-bars::before, +.menu-toggle-bars::after { + display: block; + width: 20px; + height: 2px; + background: currentColor; + position: relative; + transition: transform 200ms; +} +.menu-toggle-bars::before, +.menu-toggle-bars::after { content: ''; position: absolute; left: 0; } +.menu-toggle-bars::before { top: -6px; } +.menu-toggle-bars::after { top: 6px; } + +.sidebar-backdrop { + display: none; + position: fixed; + inset: 0; + background: rgba(0, 0, 0, 0.72); + backdrop-filter: blur(3px); + -webkit-backdrop-filter: blur(3px); + opacity: 0; + pointer-events: none; + transition: opacity 200ms ease; + z-index: 150; +} + +/* ---------- Mobile breakpoint ---------- */ +@media (max-width: 900px) { + body.sidebar-open { overflow: hidden; } + + .sidebar { + transform: translateX(-100%); + transition: transform 260ms ease; + z-index: 151; + box-shadow: 4px 0 40px rgba(0, 0, 0, 0.7); + } + body.sidebar-open .sidebar { transform: translateX(0); } + + .sidebar-backdrop { display: block; } + body.sidebar-open .sidebar-backdrop { opacity: 1; pointer-events: auto; } + + .topbar { left: 0; padding: 0 14px; gap: 10px; height: 56px; } + .topbar h1 { font-size: 12px; flex: 1; min-width: 0; letter-spacing: 0.14em; } + .topbar .status { font-size: 10px; flex-shrink: 0; } + .topbar .actions button { min-height: 44px; padding: 10px 14px; font-size: 10px; } + .menu-toggle { display: inline-flex; } + + .main { + margin-left: 0; + margin-top: 56px; + padding: 20px 16px; + padding-bottom: 180px; + } + + .field-grid { grid-template-columns: 1fr; } + + .save-bar { + left: 0; + padding: 14px 16px calc(14px + env(safe-area-inset-bottom, 0px)); + flex-wrap: wrap; + gap: 10px; + } + .save-bar > span { width: 100%; } + .save-actions { width: 100%; display: flex; flex-wrap: wrap; gap: 8px; } + .save-actions button { flex: 1 1 140px; min-height: 44px; padding: 14px 16px; font-size: 11px; } + .save-actions button:first-child { flex-basis: 100%; } + + .sidebar a { padding: 14px 20px; min-height: 44px; font-size: 12px; } + .section-header { padding: 18px 20px; } + .smart-select-display { min-height: 44px; } + #s-notifications .notif-chip { padding: 8px 12px; } + #s-notifications .notif-chip button { min-width: 28px; min-height: 28px; font-size: 18px; } + #s-notifications .notif-tab-btn, + #s-notifications .notif-add-btn, + #s-notifications .notif-presets button { min-height: 40px; padding: 10px 14px; } + #s-notifications .notif-input-row input { flex: 1 1 auto; width: auto; min-width: 0; } + + .modal-card { width: calc(100vw - 32px); min-width: 0; max-width: 420px; } + + #toast-container { right: 12px; left: 12px; top: 64px; } + .toast { max-width: none; } +} diff --git a/settings-site/public/index.html b/settings-site/public/index.html index 39d0e71..50b3e5a 100644 --- a/settings-site/public/index.html +++ b/settings-site/public/index.html @@ -11,7 +11,8 @@
-