theme-light.css is now the only file in html/ that contains a colour literal. The five page stylesheets and all four inline <style> blocks declare names and nothing else. theme-light.css 191 declarations, 175 with a literal value console.css 28 declarations, 0 work-package-suite-styles.css 16 declarations, 0 wp-chrome.css 14 declarations, 0 wp-creation-styles.css 24 declarations, 0 wp-sidenav.css 0 declarations, 0 #0f62fe is declared in one sheet, down from five. The eleven occurrences left inside theme-light.css are Carbon's own v10-to-v11 alias layer, which the inventory records as deliberate and not the S5 defect. Names were kept, because 111 var() references live in .js files across 23 token names and a rename there fails silently - no build error, no console warning, just an unstyled element. The rule the refactor was built on: consolidation is not unification. Where two sheets declared the same value, they collapse. Where they declared DIFFERENT values for one role - the two shadows, the eight status borders doing four jobs, the three mono stacks - each value got its own canonical name and the pair is recorded for T3.5. Picking a winner between two near-identical greys is a rendered change, which this task forbids. The console's zebra stripe is the one that would have bitten: #fafafa is six points from #f4f4f4, and merging them erases the striping on the nine-column user table. Collecting the one-offs in one place made two things countable that were not before: twelve distinct shadows, and a ninth amber (#8a6d00 on the field view, four points from #8e6a00 and doing the same job - BL-009). VERIFICATION - the screenshot done-when could not do the job, so it was replaced. Captured against wave 2, 11 of 14 shots were pixel-identical and 3 were not. Capturing wave 2 against ITSELF produced the same 3 differences at the same bounding box, so those shots cannot distinguish a regression from the clock. Trap 2 in the brief is half wrong: users.html is stable at both widths; the unstable third is the creator at 1440px, and admin's captured page height varies by ~600px between runs (BL-012). So tests/token_check.py was added. It checks what wave 3 actually claims: that every custom property resolves to the same literal, and every element computes the same colours, shadows and type. That is stronger than a screenshot - it covers the hover, focus and disabled rules a screenshot never exercises, and it is deterministic. wave 2 vs T3.2, all 7 pages: 178/178 wave-2 token names resolve identically, +213 new 3,500 elements compute identically, zero added, zero removed 16 tokens differ in notation only (#fff -> #ffffff), which is the duplicate class this task existed to collapse Two detours worth not repeating: the element walk was first keyed by sibling index and reported 55 phantom differences on the SOP page, where three JS-injected overlays append in whichever order their async work finishes (BL-011); and the comparator now normalises notation before reporting, because otherwise it fails on its own success. f_items 5 FIXED / F6 REPRODUCES as expected. browser_check 71/71. ONE DONE-WHEN NOT MET, recorded rather than skipped: "no page stylesheet declares a raw color, spacing or type value". The colour half is met in full. 483 raw spacing values, 281 font-sizes and 65 radii remain inside rules, 492 of them in the creator. That is arithmetic, not effort: the creator's spacing is every integer from 1px to 14px, so no token exists that padding:9px 11px maps to without changing one of the numbers - and this task forbids changing a rendered value. The two requirements are mutually exclusive. Logged as BL-010 for T5.x and T7.1, where those pages are re-laid-out and the values get chosen again. New backlog: BL-009 (ninth amber), BL-010 (raw spacing/type in rules), BL-011 (overlay append race), BL-012 (unstable screenshot targets). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
164 lines
6.2 KiB
HTML
164 lines
6.2 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title>Sign in — Work Package Suite</title>
|
|
<link rel="icon" href="favicon.ico" sizes="any">
|
|
<link rel="stylesheet" href="theme-light.css">
|
|
<style>
|
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
body {
|
|
min-height: 100vh;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
background: var(--cds-background);
|
|
padding: 1.5rem;
|
|
}
|
|
.card {
|
|
width: 100%;
|
|
max-width: 400px;
|
|
background: var(--cds-layer);
|
|
border: 1px solid var(--cds-border-subtle);
|
|
border-top: 3px solid var(--cds-interactive-01);
|
|
padding: 2.5rem 2rem;
|
|
}
|
|
.brand {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.75rem;
|
|
margin-bottom: 1.5rem;
|
|
}
|
|
.brand img { height: 36px; width: auto; }
|
|
.brand .name { font-weight: 700; font-size: 0.95rem; color: var(--cds-text-primary); }
|
|
h1 { font-size: 1.5rem; margin-bottom: 0.25rem; }
|
|
.sub { color: var(--cds-text-secondary); font-size: 0.875rem; margin-bottom: 1.75rem; }
|
|
label { display: block; font-size: 0.75rem; color: var(--cds-text-secondary); margin-bottom: 0.375rem; }
|
|
.field { margin-bottom: 1.25rem; }
|
|
input[type=text], input[type=password] {
|
|
width: 100%;
|
|
padding: 0.75rem;
|
|
font-size: 1rem;
|
|
background: var(--cds-field);
|
|
border: none;
|
|
border-bottom: 1px solid var(--cds-border-strong);
|
|
outline: 2px solid transparent;
|
|
outline-offset: -2px;
|
|
}
|
|
input:focus { outline: 2px solid var(--cds-focus); background: var(--cds-field-hover); }
|
|
button {
|
|
width: 100%;
|
|
padding: 0.875rem 1rem;
|
|
font-size: 1rem;
|
|
font-weight: 600;
|
|
color: var(--cds-text-on-color);
|
|
background: var(--cds-button-primary);
|
|
border: none;
|
|
transition: background 0.15s;
|
|
}
|
|
button:hover:not(:disabled) { background: var(--cds-hover-primary); }
|
|
button:disabled { background: var(--cds-disabled-02); cursor: not-allowed; }
|
|
.error {
|
|
display: none;
|
|
background: var(--wp-status-error-bg);
|
|
border-left: 3px solid var(--cds-support-error);
|
|
color: var(--cds-text-error);
|
|
padding: 0.75rem;
|
|
font-size: 0.8125rem;
|
|
margin-bottom: 1.25rem;
|
|
}
|
|
.error.show { display: block; }
|
|
.foot { margin-top: 1.5rem; font-size: 0.75rem; color: var(--cds-text-helper); text-align: center; }
|
|
.ok {
|
|
display: none;
|
|
background: var(--wp-status-success-bg);
|
|
border-left: 3px solid var(--cds-support-success);
|
|
color: var(--wp-hover-success);
|
|
padding: 0.75rem;
|
|
font-size: 0.8125rem;
|
|
margin-bottom: 1.25rem;
|
|
}
|
|
.ok.show { display: block; }
|
|
.note {
|
|
font-size: 0.8125rem; color: var(--cds-text-secondary);
|
|
background: var(--cds-layer-accent); border-left: 3px solid var(--cds-link-primary);
|
|
padding: 0.75rem; margin-bottom: 1.25rem;
|
|
}
|
|
.hint { font-size: 0.75rem; color: var(--cds-text-helper); margin-top: -0.75rem; margin-bottom: 1.25rem; }
|
|
a.link { color: var(--cds-link-primary); text-decoration: none; font-size: 0.8125rem; }
|
|
a.link:hover { text-decoration: underline; }
|
|
.center { text-align: center; margin-top: 1.25rem; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<main class="card">
|
|
<div class="brand">
|
|
<img src="prime-controls-logo.jpg" alt="Prime Controls" onerror="this.style.display='none'">
|
|
</div>
|
|
<div id="error" class="error" role="alert"></div>
|
|
<div id="ok" class="ok" role="status"></div>
|
|
|
|
<!-- SIGN IN -->
|
|
<section id="view-login">
|
|
<h1>Sign in</h1>
|
|
<p class="sub">Work Package Suite</p>
|
|
<form id="login-form" autocomplete="on">
|
|
<div class="field">
|
|
<label for="username">Username</label>
|
|
<input id="username" name="username" type="text" autocomplete="username" autofocus required>
|
|
</div>
|
|
<div class="field">
|
|
<label for="password">Password</label>
|
|
<input id="password" name="password" type="password" autocomplete="current-password" required>
|
|
</div>
|
|
<button id="submit" type="submit">Sign in</button>
|
|
</form>
|
|
<p class="center"><a href="#" id="forgot-link" class="link">Forgot password?</a></p>
|
|
</section>
|
|
|
|
<!-- FORGOT PASSWORD (email reset) -->
|
|
<section id="view-forgot" style="display:none">
|
|
<h1>Reset password</h1>
|
|
<p class="sub">We'll email you a link to set a new one.</p>
|
|
<div id="forgot-unavailable" class="note" style="display:none">
|
|
Password reset by email isn't switched on yet. Contact your project admin and
|
|
they'll set a new password for you. Once you're signed in you can change it
|
|
yourself from the menu in the top-right corner.
|
|
</div>
|
|
<form id="forgot-form" autocomplete="on">
|
|
<div class="field">
|
|
<label for="forgot-username">Username or email</label>
|
|
<input id="forgot-username" type="text" autocomplete="username" required>
|
|
</div>
|
|
<button id="forgot-submit" type="submit">Email me a reset link</button>
|
|
</form>
|
|
<p class="center"><a href="#" id="back-to-login" class="link">← Back to sign in</a></p>
|
|
</section>
|
|
|
|
<!-- SET A NEW PASSWORD (arrived from the emailed link) -->
|
|
<section id="view-reset" style="display:none">
|
|
<h1>Set a new password</h1>
|
|
<p class="sub">Choose a password you don't use anywhere else.</p>
|
|
<form id="reset-form" autocomplete="on">
|
|
<div class="field">
|
|
<label for="new-password">New password</label>
|
|
<input id="new-password" type="password" autocomplete="new-password" autofocus required>
|
|
</div>
|
|
<div class="hint">At least 12 characters.</div>
|
|
<div class="field">
|
|
<label for="new-password2">Confirm new password</label>
|
|
<input id="new-password2" type="password" autocomplete="new-password" required>
|
|
</div>
|
|
<button id="reset-submit" type="submit">Set password & sign in</button>
|
|
</form>
|
|
<p class="center"><a href="#" id="reset-to-login" class="link">← Back to sign in</a></p>
|
|
</section>
|
|
|
|
<p class="foot">Authorized use only · BTG / Pilot</p>
|
|
</main>
|
|
|
|
<script src="login.js"></script>
|
|
</body>
|
|
</html>
|