Initial commit: Conjuga Spanish conjugation app

Includes SwiftData dual-store architecture (local reference + CloudKit user data),
JSON-based data seeding, 20 tense guides, 20 grammar notes, SRS review system,
course vocabulary, and widget support.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Trey t
2026-04-09 20:58:33 -05:00
commit 4b467ec136
95 changed files with 82599 additions and 0 deletions

View File

@@ -0,0 +1,474 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Conjuga — Icon #5 Variations</title>
<link href="https://fonts.googleapis.com/css2?family=Space+Mono:wght@400;700&family=Playfair+Display:wght@700;900&family=JetBrains+Mono:wght@500;700;800&family=DM+Serif+Display&family=Instrument+Serif&display=swap" rel="stylesheet">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
background: #0a0a0a;
color: #fff;
font-family: system-ui, -apple-system, sans-serif;
display: flex;
flex-direction: column;
align-items: center;
padding: 60px 20px;
}
h1 {
font-family: 'Instrument Serif', serif;
font-size: 2.6rem;
margin-bottom: 6px;
letter-spacing: -1px;
}
.subtitle { color: #666; font-size: 1rem; margin-bottom: 60px; }
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 48px;
max-width: 1500px;
width: 100%;
}
.option {
display: flex;
flex-direction: column;
align-items: center;
gap: 20px;
}
.icon-wrap {
width: 200px;
height: 200px;
border-radius: 44px;
overflow: hidden;
box-shadow: 0 20px 60px rgba(0,0,0,0.5), 0 0 0 1px rgba(255,255,255,0.06);
position: relative;
}
.label { text-align: center; }
.label h3 { font-family: 'DM Serif Display', serif; font-size: 1.3rem; margin-bottom: 4px; }
.label p { color: #888; font-size: 0.85rem; max-width: 260px; }
/* ═══════════════════════════════════════
5A: Original refined — tighter, cleaner
═══════════════════════════════════════ */
.icon-5a {
background: #0C0A09;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
position: relative;
overflow: hidden;
}
.icon-5a::before {
content: '';
position: absolute;
inset: 0;
background: radial-gradient(circle at 50% 45%, rgba(249,115,22,0.1) 0%, transparent 55%);
}
.icon-5a .formula {
display: flex;
align-items: baseline;
gap: 4px;
z-index: 1;
margin-bottom: 8px;
}
.icon-5a .stem {
font-family: 'JetBrains Mono', monospace;
font-size: 24px;
font-weight: 700;
color: #F97316;
}
.icon-5a .op {
font-family: 'JetBrains Mono', monospace;
font-size: 18px;
color: #44403c;
}
.icon-5a .ending {
font-family: 'JetBrains Mono', monospace;
font-size: 24px;
font-weight: 700;
color: #22D3EE;
}
.icon-5a .result {
font-family: 'Playfair Display', serif;
font-size: 52px;
font-weight: 900;
color: white;
z-index: 1;
letter-spacing: -2px;
}
.icon-5a .glow {
width: 80px;
height: 2px;
background: linear-gradient(90deg, transparent, #F97316, transparent);
margin-top: 8px;
z-index: 1;
}
/* ═══════════════════════════════════════
5B: Ember glow — warm radial behind result
═══════════════════════════════════════ */
.icon-5b {
background: #0C0A09;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
position: relative;
overflow: hidden;
}
.icon-5b::before {
content: '';
position: absolute;
width: 160px;
height: 160px;
border-radius: 50%;
background: radial-gradient(circle, rgba(249,115,22,0.2) 0%, rgba(234,88,12,0.08) 40%, transparent 70%);
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.icon-5b .formula {
display: flex;
align-items: baseline;
gap: 3px;
z-index: 1;
margin-bottom: 4px;
opacity: 0.7;
}
.icon-5b .stem {
font-family: 'JetBrains Mono', monospace;
font-size: 16px;
font-weight: 500;
color: #FB923C;
}
.icon-5b .op {
font-family: 'JetBrains Mono', monospace;
font-size: 14px;
color: #57534e;
}
.icon-5b .ending {
font-family: 'JetBrains Mono', monospace;
font-size: 16px;
font-weight: 500;
color: #67E8F9;
}
.icon-5b .result {
font-family: 'Playfair Display', serif;
font-size: 58px;
font-weight: 900;
color: white;
z-index: 1;
letter-spacing: -2px;
text-shadow: 0 0 40px rgba(249,115,22,0.3);
}
.icon-5b .brand {
font-family: 'JetBrains Mono', monospace;
font-size: 9px;
color: #44403c;
letter-spacing: 5px;
text-transform: uppercase;
margin-top: 10px;
z-index: 1;
}
/* ═══════════════════════════════════════
5C: Split color — stem orange, ending cyan
The result word is split-colored
═══════════════════════════════════════ */
.icon-5c {
background: linear-gradient(170deg, #0f0d0c, #1a1412);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
position: relative;
overflow: hidden;
}
.icon-5c::before {
content: '';
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 2px;
background: linear-gradient(90deg, #F97316, #22D3EE);
}
.icon-5c .top-line {
position: absolute;
top: 0; left: 0; right: 0;
height: 2px;
background: linear-gradient(90deg, #F97316, #22D3EE);
}
.icon-5c .result {
z-index: 1;
font-family: 'Playfair Display', serif;
font-size: 56px;
font-weight: 900;
letter-spacing: -2px;
line-height: 1;
}
.icon-5c .result .s { color: #FB923C; }
.icon-5c .result .e { color: #22D3EE; }
.icon-5c .formula {
display: flex;
align-items: center;
gap: 6px;
z-index: 1;
margin-top: 10px;
}
.icon-5c .formula span {
font-family: 'JetBrains Mono', monospace;
font-size: 12px;
padding: 2px 8px;
border-radius: 4px;
}
.icon-5c .formula .tag-s {
color: #FB923C;
border: 1px solid rgba(249,115,22,0.3);
}
.icon-5c .formula .tag-plus {
color: #57534e;
}
.icon-5c .formula .tag-e {
color: #22D3EE;
border: 1px solid rgba(34,211,238,0.3);
}
/* ═══════════════════════════════════════
5D: Minimal mono — stark, ultra-clean
Just the formula, nothing else
═══════════════════════════════════════ */
.icon-5d {
background: #000;
display: flex;
align-items: center;
justify-content: center;
position: relative;
}
.icon-5d .content {
display: flex;
align-items: baseline;
gap: 2px;
z-index: 1;
}
.icon-5d .stem {
font-family: 'JetBrains Mono', monospace;
font-size: 38px;
font-weight: 800;
color: #F97316;
}
.icon-5d .ending {
font-family: 'JetBrains Mono', monospace;
font-size: 38px;
font-weight: 800;
color: #22D3EE;
}
.icon-5d .cursor {
width: 3px;
height: 40px;
background: rgba(255,255,255,0.6);
margin-left: 2px;
animation: blink 1.2s step-end infinite;
align-self: center;
}
@keyframes blink {
0%, 100% { opacity: 1; }
50% { opacity: 0; }
}
/* ═══════════════════════════════════════
5E: Layered depth — multiple verb forms
stacked with depth, formula on top
═══════════════════════════════════════ */
.icon-5e {
background: #0C0A09;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
position: relative;
overflow: hidden;
}
.icon-5e::before {
content: '';
position: absolute;
inset: 0;
background: radial-gradient(ellipse at 50% 70%, rgba(249,115,22,0.06) 0%, transparent 60%);
}
.icon-5e .bg-forms {
position: absolute;
z-index: 0;
display: flex;
flex-direction: column;
align-items: center;
gap: 3px;
opacity: 0.12;
}
.icon-5e .bg-forms span {
font-family: 'JetBrains Mono', monospace;
font-size: 13px;
color: white;
}
.icon-5e .main-formula {
display: flex;
align-items: baseline;
gap: 4px;
z-index: 1;
margin-bottom: 6px;
}
.icon-5e .main-formula .stem {
font-family: 'JetBrains Mono', monospace;
font-size: 26px;
font-weight: 700;
color: #F97316;
}
.icon-5e .main-formula .op {
font-family: 'JetBrains Mono', monospace;
font-size: 18px;
color: #44403c;
}
.icon-5e .main-formula .ending {
font-family: 'JetBrains Mono', monospace;
font-size: 26px;
font-weight: 700;
color: #22D3EE;
}
.icon-5e .result {
font-family: 'Playfair Display', serif;
font-size: 46px;
font-weight: 900;
color: white;
z-index: 1;
letter-spacing: -1px;
}
.icon-5e .other-forms {
display: flex;
gap: 8px;
margin-top: 10px;
z-index: 1;
}
.icon-5e .other-forms span {
font-family: 'JetBrains Mono', monospace;
font-size: 10px;
color: #57534e;
}
.icon-5e .other-forms .active {
color: #FB923C;
}
</style>
</head>
<body>
<h1>Icon #5 — Variations</h1>
<p class="subtitle">Neon Grammar refined five ways</p>
<div class="grid">
<!-- 5A: Original refined -->
<div class="option">
<div class="icon-wrap icon-5a">
<div class="formula">
<span class="stem">habl</span>
<span class="op">+</span>
<span class="ending">o</span>
</div>
<div class="result">hablo</div>
<div class="glow"></div>
</div>
<div class="label">
<h3>5A. Clean Formula</h3>
<p>Tighter spacing, no brand text. Formula + result, amber glow underneath.</p>
</div>
</div>
<!-- 5B: Ember glow -->
<div class="option">
<div class="icon-wrap icon-5b">
<div class="formula">
<span class="stem">habl</span>
<span class="op">+</span>
<span class="ending">o</span>
</div>
<div class="result">hablo</div>
<div class="brand">conjuga</div>
</div>
<div class="label">
<h3>5B. Ember Glow</h3>
<p>Warm radial glow behind the result. Formula faded, word glows. Brand text below.</p>
</div>
</div>
<!-- 5C: Split color -->
<div class="option">
<div class="icon-wrap icon-5c">
<div class="top-line"></div>
<div class="result"><span class="s">habl</span><span class="e">o</span></div>
<div class="formula">
<span class="tag-s">stem</span>
<span class="tag-plus">+</span>
<span class="tag-e">ending</span>
</div>
</div>
<div class="label">
<h3>5C. Split Color</h3>
<p>The word itself is two-toned — stem in orange, ending in cyan. Gradient borders top and bottom.</p>
</div>
</div>
<!-- 5D: Minimal mono -->
<div class="option">
<div class="icon-wrap icon-5d">
<div class="content">
<span class="stem">habl</span><span class="ending">o</span>
<div class="cursor"></div>
</div>
</div>
<div class="label">
<h3>5D. Terminal</h3>
<p>Pure black, just the split-colored word with a blinking cursor. Stark, developer-feel.</p>
</div>
</div>
<!-- 5E: Layered depth -->
<div class="option">
<div class="icon-wrap icon-5e">
<div class="bg-forms">
<span>hablamos</span>
<span>habláis</span>
<span>hablan</span>
<span>hablas</span>
<span>habla</span>
</div>
<div class="main-formula">
<span class="stem">habl</span>
<span class="op">+</span>
<span class="ending">o</span>
</div>
<div class="result">hablo</div>
<div class="other-forms">
<span class="active">yo</span>
<span></span>
<span>él</span>
<span>nos</span>
<span>ellos</span>
</div>
</div>
<div class="label">
<h3>5E. Layered Depth</h3>
<p>Ghost conjugations in background, formula + result in front. Shows the full table subtly.</p>
</div>
</div>
</div>
</body>
</html>