/* Google Fonts — must come before the Tailwind import */ @import url("https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Lora:wght@600;700&display=swap"); @import "tailwindcss"; /* ============================================================================= Mr. Drew's Assignment Creator — design system Identity: a well-kept teacher's desk. Lora serif headings, chalkboard green for primary actions, and the signature: everything answer-key wears red pen — the color teachers actually grade in. ============================================================================= */ @layer base { :root { /* palette */ --paper: #f0f4f1; --panel: #ffffff; --ink: #1e2d28; --ink-soft: #58706a; --board: #2f6b58; --board-deep: #245546; --board-tint: #e4eeea; --board-glow: rgba(47, 107, 88, 0.12); --redpen: #b8412f; --redpen-tint: #faece9; --gold: #b98a23; --gold-tint: #faf3e2; --line: #dde4df; --line-strong: #c5d0cb; --field-bg: #ffffff; --hover-bg: #f2f6f4; --tab-track: #e6ecea; --chip-neutral-bg: #eaeeec; --empty-bg: #fafcfb; --shadow-sm: 0 1px 3px rgba(34, 49, 44, 0.07), 0 2px 8px rgba(34, 49, 44, 0.05); --shadow: 0 2px 6px rgba(34, 49, 44, 0.06), 0 6px 20px rgba(34, 49, 44, 0.07); --shadow-lg: 0 8px 32px rgba(34, 49, 44, 0.12), 0 2px 8px rgba(34, 49, 44, 0.06); color-scheme: light; /* type */ --font-display: "Lora", "Iowan Old Style", "Palatino Linotype", Georgia, serif; --font-body: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; --font-mono: ui-monospace, SFMono-Regular, "Cascadia Mono", Consolas, Menlo, monospace; --radius: 12px; --radius-sm: 8px; --radius-xs: 5px; --transition: 0.18s ease; --transition-fast: 0.1s ease; } /* The same desk after dark */ html[data-theme="dark"] { --paper: #111815; --panel: #1b2320; --ink: #e2eae5; --ink-soft: #92aaa2; --board: #4d9c82; --board-deep: #7bc0a8; --board-tint: #1e3028; --board-glow: rgba(77, 156, 130, 0.15); --redpen: #e07a63; --redpen-tint: #38221e; --gold: #d3a94c; --gold-tint: #342d1a; --line: #263028; --line-strong: #374440; --field-bg: #151c18; --hover-bg: #1f2a26; --tab-track: #161d1a; --chip-neutral-bg: #262f2b; --empty-bg: #171e1a; --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.3), 0 2px 8px rgba(0, 0, 0, 0.25); --shadow: 0 2px 6px rgba(0, 0, 0, 0.3), 0 6px 20px rgba(0, 0, 0, 0.3); --shadow-lg: 0 8px 32px rgba(0, 0, 0, 0.4), 0 2px 8px rgba(0, 0, 0, 0.3); color-scheme: dark; } html[data-theme="dark"] .alert-error { border-color: #5a2f26; color: #f0a795; } html[data-theme="dark"] .alert-warn { border-color: #564820; color: #e2c47e; } html[data-theme="dark"] .alert-info { border-color: #2d5040; color: #8dcbb5; } html[data-theme="dark"] .toast { background: #e2eae5; color: #111815; } html[data-theme="dark"] .brand-mark { color: #f1f5f2; } html[data-theme="dark"] .nav-scrolled { box-shadow: 0 4px 24px rgba(0,0,0,0.5); } * { box-sizing: border-box; } html, body { margin: 0; padding: 0; background: var(--paper); color: var(--ink); font-family: var(--font-body); font-size: 15.5px; line-height: 1.58; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } h1, h2, h3 { font-family: var(--font-display); font-weight: 700; letter-spacing: -0.01em; margin: 0; line-height: 1.25; } h1 { font-size: 1.85rem; } h2 { font-size: 1.3rem; } h3 { font-size: 1.08rem; } a { color: var(--board); text-decoration: none; } a:hover { text-decoration: underline; } :focus-visible { outline: 2px solid var(--board); outline-offset: 2px; border-radius: 4px; } @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation: none !important; transition: none !important; } } } /* ===================================================================== KEYFRAME ANIMATIONS ===================================================================== */ @keyframes spin { to { transform: rotate(360deg); } } @keyframes fade-in-up { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } @keyframes fade-in { from { opacity: 0; } to { opacity: 1; } } @keyframes slide-up { from { opacity: 0; transform: translate(-50%, 12px); } to { opacity: 1; transform: translate(-50%, 0); } } @keyframes step-complete { 0% { transform: scale(1); } 50% { transform: scale(1.2); } 100% { transform: scale(1); } } @keyframes skeleton-pulse { 0%, 100% { opacity: 0.55; } 50% { opacity: 1; } } @keyframes progress-fill { from { width: 0%; } to { width: 100%; } } @keyframes spin-ring { 0% { transform: rotate(0deg); stroke-dashoffset: 60; } 50% { stroke-dashoffset: 15; } 100% { transform: rotate(360deg); stroke-dashoffset: 60; } } /* ===================================================================== LAYOUT SHELL ===================================================================== */ @layer components { .shell { max-width: 1020px; margin: 0 auto; padding: 32px 22px 90px; } /* ---------- navigation ---------- */ .topnav { background: rgba(255, 255, 255, 0.85); backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); border-bottom: 1px solid var(--line); position: sticky; top: 0; z-index: 50; transition: box-shadow var(--transition); } html[data-theme="dark"] .topnav { background: rgba(27, 35, 32, 0.85); } .topnav.nav-scrolled { box-shadow: 0 4px 24px rgba(34, 49, 44, 0.1); border-bottom-color: var(--line-strong); } .topnav-inner { max-width: 1020px; margin: 0 auto; padding: 0 22px; display: flex; align-items: center; gap: 24px; height: 60px; } .brand { font-family: var(--font-display); font-size: 1.08rem; font-weight: 700; color: var(--ink); display: flex; align-items: center; gap: 10px; white-space: nowrap; } .brand:hover { text-decoration: none; } .brand-mark { width: 30px; height: 30px; border-radius: 8px; background: linear-gradient(135deg, var(--board) 0%, var(--board-deep) 100%); color: #fff; display: inline-flex; align-items: center; justify-content: center; font-size: 15px; flex: none; box-shadow: 0 2px 6px rgba(47, 107, 88, 0.35); } .navlinks { display: flex; gap: 2px; margin-left: auto; } .theme-toggle { flex: none; width: 36px; height: 36px; border-radius: 9px; font-size: 1rem; transition: background var(--transition), transform var(--transition-fast); } .theme-toggle:hover { transform: rotate(18deg); } .navlink { padding: 7px 14px; border-radius: var(--radius-sm); color: var(--ink-soft); font-weight: 500; font-size: 0.93rem; transition: background var(--transition), color var(--transition); } .navlink:hover { background: var(--hover-bg); color: var(--ink); text-decoration: none; } .navlink.active { background: var(--board-tint); color: var(--board-deep); font-weight: 600; } /* ---------- cards & panels ---------- */ .card { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow-sm); padding: 24px; transition: box-shadow var(--transition), border-color var(--transition), transform 0.2s ease; animation: fade-in-up 0.3s ease both; } .card + .card { margin-top: 16px; } .card:hover { box-shadow: var(--shadow); } .card-lift:hover { box-shadow: var(--shadow-lg); transform: translateY(-2px); border-color: var(--line-strong); } .page-head { margin: 4px 0 24px; } .page-head p { color: var(--ink-soft); margin: 8px 0 0; max-width: 62ch; font-size: 0.97rem; } /* ---------- buttons ---------- */ .btn { appearance: none; border: 1px solid var(--line-strong); background: var(--panel); color: var(--ink); font: inherit; font-family: var(--font-body); font-weight: 600; font-size: 0.92rem; padding: 9px 17px; border-radius: var(--radius-sm); cursor: pointer; display: inline-flex; align-items: center; gap: 7px; transition: background var(--transition), border-color var(--transition), box-shadow var(--transition), transform var(--transition-fast); white-space: nowrap; user-select: none; } .btn:hover { background: var(--hover-bg); border-color: var(--board); box-shadow: 0 1px 4px var(--board-glow); } .btn:active { transform: translateY(1px); box-shadow: none; } .btn:disabled { opacity: 0.45; cursor: not-allowed; transform: none; box-shadow: none; } .btn-primary { background: var(--board); border-color: var(--board); color: #fff; box-shadow: 0 2px 6px rgba(47, 107, 88, 0.25); } .btn-primary:hover { background: var(--board-deep); border-color: var(--board-deep); box-shadow: 0 4px 14px rgba(47, 107, 88, 0.35); } .btn-danger { color: var(--redpen); border-color: var(--line-strong); } .btn-danger:hover { background: var(--redpen-tint); border-color: var(--redpen); box-shadow: none; } .btn-sm { padding: 5px 11px; font-size: 0.84rem; border-radius: var(--radius-xs); } .btn-lg { padding: 12px 26px; font-size: 1rem; border-radius: var(--radius); } /* ---------- forms ---------- */ label.field { display: block; margin-bottom: 14px; } .field-label { display: block; font-weight: 600; font-size: 0.87rem; margin-bottom: 5px; color: var(--ink); letter-spacing: 0.01em; } .field-hint { font-size: 0.82rem; color: var(--ink-soft); margin-top: 5px; line-height: 1.5; } input[type="text"], input[type="password"], input[type="number"], input[type="url"], select, textarea { width: 100%; font: inherit; font-family: var(--font-body); color: var(--ink); background: var(--field-bg); border: 1.5px solid var(--line-strong); border-radius: var(--radius-sm); padding: 9px 12px; transition: border-color var(--transition), box-shadow var(--transition), background var(--transition); } input:focus, select:focus, textarea:focus { border-color: var(--board); outline: none; box-shadow: 0 0 0 3px var(--board-glow); background: var(--field-bg); } textarea { resize: vertical; min-height: 80px; } .row { display: flex; gap: 14px; flex-wrap: wrap; } .row > * { flex: 1; min-width: 180px; } .check { display: flex; align-items: flex-start; gap: 10px; margin: 10px 0; cursor: pointer; padding: 8px 10px; border-radius: var(--radius-xs); transition: background var(--transition); } .check:hover { background: var(--hover-bg); } .check input { width: 16px; height: 16px; margin-top: 3px; accent-color: var(--board); cursor: pointer; flex: none; } .check span { font-size: 0.94rem; } .check small { display: block; color: var(--ink-soft); } /* ---------- step tabs (Create flow) ---------- */ .steps { display: flex; gap: 0; border-bottom: 1.5px solid var(--line); margin-bottom: 24px; overflow: hidden; } .step { display: flex; align-items: center; gap: 10px; padding: 12px 20px 13px; margin-bottom: -1.5px; border-bottom: 2.5px solid transparent; color: var(--ink-soft); font-weight: 500; font-size: 0.93rem; background: none; border-top: 0; border-left: 0; border-right: 0; cursor: pointer; font-family: var(--font-body); transition: color var(--transition), border-color var(--transition); } .step .step-n { width: 24px; height: 24px; border-radius: 50%; flex: none; border: 2px solid currentColor; display: inline-flex; align-items: center; justify-content: center; font-size: 0.78rem; font-weight: 700; transition: background var(--transition), border-color var(--transition), transform 0.2s ease; } .step.active { color: var(--board-deep); border-bottom-color: var(--board); font-weight: 600; } .step.done { color: var(--board); } .step.done .step-n { background: var(--board); border-color: var(--board); color: #fff; animation: step-complete 0.3s ease; } .step:disabled { cursor: default; opacity: 0.5; } /* ---------- choice cards ---------- */ .choice-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 10px; } .choice { border: 1.5px solid var(--line-strong); border-radius: var(--radius); background: var(--field-bg); padding: 14px 15px; cursor: pointer; text-align: left; font: inherit; font-family: var(--font-body); transition: border-color var(--transition), background var(--transition), box-shadow var(--transition), transform 0.15s ease; } .choice:hover { border-color: var(--board); box-shadow: 0 2px 10px var(--board-glow); transform: translateY(-1px); } .choice.selected { border-color: var(--board); background: var(--board-tint); box-shadow: 0 2px 10px var(--board-glow); } .choice b { display: block; font-size: 0.93rem; font-weight: 600; } .choice small { color: var(--ink-soft); font-size: 0.79rem; line-height: 1.35; display: block; margin-top: 4px; } /* ---------- tabs (source input) ---------- */ .tabs { display: inline-flex; background: var(--tab-track); border-radius: var(--radius-sm); padding: 3px; gap: 2px; margin-bottom: 16px; } .tab { border: 0; background: none; font: inherit; font-family: var(--font-body); font-weight: 600; font-size: 0.88rem; padding: 7px 16px; border-radius: 6px; cursor: pointer; color: var(--ink-soft); transition: background var(--transition), color var(--transition), box-shadow var(--transition); } .tab.active { background: var(--panel); color: var(--ink); box-shadow: var(--shadow-sm); } /* ---------- badges & chips ---------- */ .chip { display: inline-flex; align-items: center; gap: 5px; font-size: 0.73rem; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; padding: 3px 10px; border-radius: 99px; background: var(--board-tint); color: var(--board-deep); } .chip-neutral { background: var(--chip-neutral-bg); color: var(--ink-soft); } .stamp { display: inline-flex; align-items: center; gap: 5px; font-family: var(--font-mono); font-size: 0.71rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; padding: 3px 8px; border: 1.5px solid currentColor; border-radius: 4px; transform: rotate(-1.2deg); } .stamp-pass { color: var(--board); background: rgba(47, 107, 88, 0.06); } .stamp-warn { color: var(--gold); background: var(--gold-tint); transform: rotate(1deg); } /* ---------- answer key (red pen) ---------- */ .answer-key { margin-top: 14px; padding: 13px 15px; background: var(--redpen-tint); border-left: 3px solid var(--redpen); border-radius: 0 var(--radius-sm) var(--radius-sm) 0; } .answer-key .ak-label { font-family: var(--font-mono); font-size: 0.69rem; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; color: var(--redpen); display: block; margin-bottom: 6px; } .answer-key, .answer-key textarea, .answer-key input { font-size: 0.92rem; } .redpen { color: var(--redpen); font-weight: 600; } /* ---------- question cards ---------- */ .qcard { position: relative; } .qcard-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 14px; } .qnum { font-family: var(--font-display); font-size: 1.15rem; font-weight: 700; color: var(--board-deep); min-width: 28px; } .qcard-actions { margin-left: auto; display: flex; gap: 6px; flex-wrap: wrap; } .icon-btn { border: 1px solid var(--line); background: var(--field-bg); border-radius: 7px; width: 32px; height: 32px; cursor: pointer; font-size: 0.93rem; line-height: 1; display: inline-flex; align-items: center; justify-content: center; color: var(--ink-soft); transition: background var(--transition), border-color var(--transition), color var(--transition), transform var(--transition-fast); } .icon-btn:hover { border-color: var(--board); color: var(--ink); background: var(--board-tint); transform: scale(1.05); } .icon-btn:disabled { opacity: 0.3; cursor: default; transform: none; } .icon-btn.danger:hover { border-color: var(--redpen); color: var(--redpen); background: var(--redpen-tint); } .opt-row { display: flex; align-items: center; gap: 9px; margin: 7px 0; } .opt-row input[type="radio"] { accent-color: var(--redpen); width: 16px; height: 16px; flex: none; cursor: pointer; } .opt-letter { font-weight: 700; font-size: 0.84rem; color: var(--ink-soft); width: 18px; flex: none; } .points-input { width: 64px !important; text-align: center; } /* ---------- alerts & toasts ---------- */ .alert { padding: 13px 16px; border-radius: var(--radius-sm); font-size: 0.92rem; margin: 14px 0; border: 1px solid; animation: fade-in 0.2s ease; } .alert-error { background: var(--redpen-tint); border-color: #e8c5be; color: #8c3022; } .alert-warn { background: var(--gold-tint); border-color: #e9d8a6; color: #7a5a14; } .alert-info { background: var(--board-tint); border-color: #cde0d8; color: var(--board-deep); } .toast { position: fixed; bottom: 24px; left: 50%; transform: translateX(-50%); background: var(--ink); color: #fff; padding: 11px 22px; border-radius: 99px; font-size: 0.91rem; font-weight: 600; box-shadow: 0 8px 30px rgba(0,0,0,0.3); z-index: 100; animation: slide-up 0.22s cubic-bezier(0.34, 1.56, 0.64, 1) both; white-space: nowrap; } /* ---------- spinner ---------- */ .spinner { width: 16px; height: 16px; border-radius: 50%; flex: none; border: 2px solid rgba(47, 107, 88, 0.22); border-top-color: var(--board); animation: spin 0.7s linear infinite; display: inline-block; vertical-align: -3px; } /* ---------- generation progress ---------- */ .progress-list { list-style: none; margin: 22px 0 0; padding: 0; } .progress-list li { display: flex; align-items: center; gap: 12px; padding: 11px 0; font-size: 0.97rem; color: var(--ink-soft); border-bottom: 1px solid var(--line); opacity: 0; animation: fade-in-up 0.35s ease forwards; } .progress-list li:last-child { border-bottom: none; } .progress-list li:nth-child(1) { animation-delay: 0.0s; } .progress-list li:nth-child(2) { animation-delay: 0.08s; } .progress-list li:nth-child(3) { animation-delay: 0.16s; } .progress-list li:nth-child(4) { animation-delay: 0.24s; } .progress-list li.active { color: var(--ink); font-weight: 600; } .progress-list li.done { color: var(--board); } .progress-dot { width: 20px; text-align: center; flex: none; font-size: 1rem; } /* ---------- library ---------- */ .lib-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(276px, 1fr)); gap: 16px; } .lib-card { animation: fade-in-up 0.35s ease both; } .lib-card:nth-child(2) { animation-delay: 0.06s; } .lib-card:nth-child(3) { animation-delay: 0.12s; } .lib-card:nth-child(4) { animation-delay: 0.18s; } .lib-card:nth-child(5) { animation-delay: 0.24s; } .lib-card:nth-child(6) { animation-delay: 0.30s; } .lib-card h3 { margin-bottom: 6px; } .lib-meta { color: var(--ink-soft); font-size: 0.83rem; margin: 3px 0 14px; line-height: 1.55; } .lib-actions { display: flex; gap: 7px; } /* Skeleton loader */ .skeleton-card { animation: skeleton-pulse 1.5s ease-in-out infinite; } .skeleton-line { background: var(--line); border-radius: 5px; height: 14px; margin-bottom: 10px; } .skeleton-line.short { width: 55%; } .skeleton-line.medium { width: 75%; } .skeleton-line.full { width: 100%; } .skeleton-chip { background: var(--line); border-radius: 99px; height: 20px; width: 64px; margin-bottom: 12px; } .empty { text-align: center; padding: 60px 24px; color: var(--ink-soft); border: 1.5px dashed var(--line-strong); border-radius: var(--radius); background: var(--empty-bg); animation: fade-in 0.3s ease; } .empty h3 { color: var(--ink); margin-bottom: 8px; } /* ---------- provider cards on settings ---------- */ .provider-row { display: flex; align-items: center; gap: 12px; padding: 13px 15px; border: 1.5px solid var(--line-strong); border-radius: var(--radius); cursor: pointer; background: var(--field-bg); margin-bottom: 10px; transition: border-color var(--transition), background var(--transition), box-shadow var(--transition); } .provider-row:hover { border-color: var(--board); background: var(--hover-bg); } .provider-row.selected { border-color: var(--board); background: var(--board-tint); box-shadow: 0 2px 8px var(--board-glow); } .provider-row input { accent-color: var(--board); width: 17px; height: 17px; flex: none; } .provider-row b { font-size: 0.96rem; } .provider-row small { color: var(--ink-soft); display: block; } .local-tag { margin-left: auto; } /* ---------- misc helpers ---------- */ .muted { color: var(--ink-soft); } .small { font-size: 0.84rem; } .spacer { flex: 1; } .hr { border: 0; border-top: 1px solid var(--line); margin: 20px 0; } @media (max-width: 640px) { .shell { padding: 20px 15px 74px; } .topnav-inner { gap: 10px; padding: 0 15px; } .brand span.brand-text { display: none; } .card { padding: 18px; } .steps { overflow-x: auto; } h1 { font-size: 1.5rem; } } }