Back to CSS Neumorphism Sunken Form Studio CSS + JS
Share
HTML
<section class="nm-frm" aria-label="Sunken form studio">
  <div class="card">

    <div>
      <div class="sec-tag">01 — Search Input</div>
      <div class="search-wrap">
        <span class="search-icon" aria-hidden="true">⌕</span>
        <input type="text" class="search-field" placeholder="Search components, patterns, use cases…" data-nm-frm-search />
        <button type="button" class="search-clear" data-nm-frm-clear aria-label="Clear search">✕</button>
      </div>
      <div class="search-chips" role="tablist">
        <button type="button" class="chip active" data-nm-frm-chip>All</button>
        <button type="button" class="chip" data-nm-frm-chip>Buttons</button>
        <button type="button" class="chip" data-nm-frm-chip>Cards</button>
        <button type="button" class="chip" data-nm-frm-chip>Sliders</button>
        <button type="button" class="chip" data-nm-frm-chip>Forms</button>
        <button type="button" class="chip" data-nm-frm-chip>Dark Mode</button>
      </div>
    </div>

    <div class="div-line" aria-hidden="true"></div>

    <div>
      <div class="sec-tag">02 — Text Input Fields</div>
      <div class="field-grid">

        <div class="field-wrap">
          <label class="field-label">Full Name</label>
          <div class="input-icon-wrap">
            <span class="i-icon" aria-hidden="true">👤</span>
            <input class="neu-input valid" type="text" value="Alex Rivera" placeholder="Your full name" />
          </div>
          <span class="field-hint success">✓ Looks good!</span>
        </div>

        <div class="field-wrap">
          <label class="field-label">Email Address</label>
          <div class="input-icon-wrap">
            <span class="i-icon" aria-hidden="true">✉</span>
            <input class="neu-input invalid" type="email" value="alex@" placeholder="[email protected]" data-nm-frm-email />
          </div>
          <span class="field-hint error">✕ Please enter a valid email.</span>
        </div>

        <div class="field-wrap">
          <label class="field-label">Password</label>
          <div class="input-icon-wrap">
            <span class="i-icon" aria-hidden="true">🔒</span>
            <input class="neu-input" type="password" value="MySuperPass1" placeholder="Create a password" data-nm-frm-pw />
            <button type="button" class="i-badge" data-nm-frm-pw-toggle aria-label="Show password">👁</button>
          </div>
          <div class="strength-bar" aria-hidden="true">
            <div class="str-seg fill-strong"></div>
            <div class="str-seg fill-strong"></div>
            <div class="str-seg fill-strong"></div>
            <div class="str-seg"></div>
          </div>
          <span class="field-hint">Strength: Strong</span>
        </div>

        <div class="field-wrap">
          <label class="field-label">Country</label>
          <div class="select-wrap">
            <select class="neu-select">
              <option>🇺🇸 United States</option>
              <option>🇬🇧 United Kingdom</option>
              <option>🇩🇪 Germany</option>
              <option>🇯🇵 Japan</option>
            </select>
            <span class="select-arrow" aria-hidden="true">▾</span>
          </div>
        </div>

        <div class="field-wrap full">
          <label class="field-label">Bio / Description</label>
          <textarea class="neu-textarea" placeholder="Tell us a little about yourself…">Product designer obsessed with tactile interfaces and the space between hardware and software.</textarea>
        </div>

      </div>
    </div>

    <div class="div-line" aria-hidden="true"></div>

    <div>
      <div class="sec-tag">03 — Checkboxes &amp; Radios</div>
      <div class="check-radio-row">

        <div class="cr-group">
          <button type="button" class="cr-item checked" data-nm-frm-check>
            <span class="cr-box">✓</span>
            <span class="cr-text">Email notifications
              <small>Receive weekly digest</small>
            </span>
          </button>
          <button type="button" class="cr-item checked" data-nm-frm-check>
            <span class="cr-box">✓</span>
            <span class="cr-text">Push notifications
              <small>On mobile &amp; desktop</small>
            </span>
          </button>
          <button type="button" class="cr-item" data-nm-frm-check>
            <span class="cr-box"></span>
            <span class="cr-text">Marketing emails
              <small>Product updates &amp; offers</small>
            </span>
          </button>
        </div>

        <div class="cr-group" role="radiogroup">
          <button type="button" class="cr-item" data-nm-frm-radio>
            <span class="cr-circle"></span>
            <span class="cr-text">Starter plan
              <small>Free forever · 3 projects</small>
            </span>
          </button>
          <button type="button" class="cr-item checked" data-nm-frm-radio>
            <span class="cr-circle"></span>
            <span class="cr-text">Pro plan
              <small>$12/mo · Unlimited</small>
            </span>
          </button>
          <button type="button" class="cr-item" data-nm-frm-radio>
            <span class="cr-circle"></span>
            <span class="cr-text">Enterprise
              <small>Custom pricing · SSO</small>
            </span>
          </button>
        </div>

      </div>
    </div>

    <div class="submit-row">
      <button type="button" class="btn-submit">Create Account →</button>
      <button type="button" class="btn-cancel">Cancel</button>
      <span class="form-note">SSL secured · No spam</span>
    </div>

  </div>
</section>
CSS
/* ─── 06 Sunken Form Studio — sage mist neumorphic forms ───────────── */
@import url('https://fonts.googleapis.com/css2?family=Mulish:wght@300;400;500;600;700&family=DM+Mono:wght@400;500&display=swap');

.nm-frm {
  --nm-frm-bg:  #eaf0ee;
  --nm-frm-sd:  #c8d4cc;
  --nm-frm-sl:  #f8fff8;
  --nm-frm-ib:  #e2ece6;
  --nm-frm-acc: #3a7d54;
  --nm-frm-ac2: #5aaf7a;
  --nm-frm-ac3: #2a5c3c;
  --nm-frm-txt: #5a6e62;
  --nm-frm-txt2:#1a3028;
  --nm-frm-err: #c05050;
  --nm-frm-warn:#c09040;
  --nm-frm-r:   16px;
  --nm-frm-neu-in:    inset 6px 6px 14px var(--nm-frm-sd), inset -6px -6px 14px var(--nm-frm-sl);
  --nm-frm-neu-sm:    5px 5px 12px var(--nm-frm-sd), -5px -5px 12px var(--nm-frm-sl);
  --nm-frm-neu-sm-in: inset 4px 4px 9px var(--nm-frm-sd), inset -4px -4px 9px var(--nm-frm-sl);

  position: relative;
  width: 100%;
  min-height: 880px;
  background: var(--nm-frm-bg);
  font-family: 'Mulish', system-ui, sans-serif;
  color: var(--nm-frm-txt);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 32px 16px;
  overflow: hidden;
  box-sizing: border-box;
}

.nm-frm *,
.nm-frm *::before,
.nm-frm *::after { box-sizing: border-box; }

.nm-frm .card {
  position: relative;
  width: 100%;
  max-width: 820px;
  background: var(--nm-frm-bg);
  border-radius: 40px;
  padding: 44px 40px;
  box-shadow: 22px 22px 54px var(--nm-frm-sd), -22px -22px 54px var(--nm-frm-sl);
  display: flex;
  flex-direction: column;
  gap: 28px;
}

.nm-frm .sec-tag {
  font-family: 'DM Mono', ui-monospace, monospace;
  font-size: 9px;
  font-weight: 500;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: var(--nm-frm-txt);
  opacity: 0.55;
  margin-bottom: 16px;
}

/* Search */
.nm-frm .search-wrap { position: relative; }
.nm-frm .search-field {
  width: 100%;
  height: 56px;
  border: none;
  outline: none;
  border-radius: 28px;
  background: var(--nm-frm-bg);
  box-shadow: var(--nm-frm-neu-in);
  padding: 0 56px 0 52px;
  font-family: 'Mulish', system-ui, sans-serif;
  font-size: 15px;
  font-weight: 500;
  color: var(--nm-frm-txt2);
  transition: box-shadow 0.25s ease;
}
.nm-frm .search-field::placeholder { color: var(--nm-frm-txt); opacity: 0.5; }
.nm-frm .search-field:focus {
  box-shadow: inset 7px 7px 16px var(--nm-frm-sd), inset -7px -7px 16px var(--nm-frm-sl),
              0 0 0 2px rgba(58, 125, 84, 0.2);
}
.nm-frm .search-icon {
  position: absolute;
  left: 20px;
  top: 50%;
  transform: translateY(-50%);
  font-size: 20px;
  pointer-events: none;
  color: var(--nm-frm-txt);
  opacity: 0.5;
}
.nm-frm .search-clear {
  position: absolute;
  right: 16px;
  top: 50%;
  transform: translateY(-50%);
  background: var(--nm-frm-bg);
  border: none;
  cursor: pointer;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-shadow: var(--nm-frm-neu-sm);
  color: var(--nm-frm-txt);
  font-size: 14px;
  transition: all 0.15s;
  opacity: 0;
}
.nm-frm .search-field:not(:placeholder-shown) ~ .search-clear { opacity: 1; }
.nm-frm .search-clear:hover { box-shadow: 6px 6px 14px var(--nm-frm-sd), -6px -6px 14px var(--nm-frm-sl); }
.nm-frm .search-clear:active { box-shadow: var(--nm-frm-neu-sm-in); }

.nm-frm .search-chips {
  display: flex;
  gap: 8px;
  margin-top: 14px;
  flex-wrap: wrap;
}
.nm-frm .chip {
  background: var(--nm-frm-bg);
  border: none;
  cursor: pointer;
  padding: 8px 16px;
  border-radius: 20px;
  font-family: 'Mulish', system-ui, sans-serif;
  font-size: 12px;
  font-weight: 600;
  color: var(--nm-frm-txt);
  box-shadow: var(--nm-frm-neu-sm);
  transition: all 0.15s;
}
.nm-frm .chip:hover { box-shadow: 6px 6px 14px var(--nm-frm-sd), -6px -6px 14px var(--nm-frm-sl); color: var(--nm-frm-acc); }
.nm-frm .chip:active { box-shadow: var(--nm-frm-neu-sm-in); }
.nm-frm .chip.active { box-shadow: var(--nm-frm-neu-sm-in); color: var(--nm-frm-acc); font-weight: 700; }

/* Field grid */
.nm-frm .field-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
}
.nm-frm .field-wrap {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.nm-frm .field-wrap.full { grid-column: 1 / -1; }
.nm-frm .field-label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.8px;
  text-transform: uppercase;
  color: var(--nm-frm-txt);
  opacity: 0.7;
  font-family: 'DM Mono', ui-monospace, monospace;
}

.nm-frm .neu-input {
  width: 100%;
  border: none;
  outline: none;
  border-radius: var(--nm-frm-r);
  background: var(--nm-frm-bg);
  box-shadow: var(--nm-frm-neu-in);
  padding: 14px 18px;
  font-family: 'Mulish', system-ui, sans-serif;
  font-size: 14px;
  font-weight: 500;
  color: var(--nm-frm-txt2);
  transition: box-shadow 0.22s ease, color 0.2s;
}
.nm-frm .neu-input::placeholder { color: var(--nm-frm-txt); opacity: 0.45; }
.nm-frm .neu-input:focus {
  box-shadow: inset 7px 7px 16px var(--nm-frm-sd), inset -7px -7px 16px var(--nm-frm-sl),
              0 0 0 2.5px rgba(58, 125, 84, 0.25);
  color: var(--nm-frm-txt2);
}
.nm-frm .neu-input.valid   { box-shadow: var(--nm-frm-neu-in), 0 0 0 2px rgba(58, 125, 84, 0.4); }
.nm-frm .neu-input.invalid { box-shadow: var(--nm-frm-neu-in), 0 0 0 2px rgba(192, 80, 80, 0.45); }

.nm-frm .input-icon-wrap { position: relative; }
.nm-frm .input-icon-wrap .neu-input { padding-left: 44px; }
.nm-frm .input-icon-wrap .i-icon {
  position: absolute;
  left: 16px;
  top: 50%;
  transform: translateY(-50%);
  font-size: 16px;
  pointer-events: none;
  opacity: 0.5;
}
.nm-frm .input-icon-wrap .i-badge {
  position: absolute;
  right: 14px;
  top: 50%;
  transform: translateY(-50%);
  font-size: 14px;
  cursor: pointer;
  opacity: 0.5;
  transition: opacity 0.15s;
  background: transparent;
  border: 0;
  padding: 4px;
}
.nm-frm .input-icon-wrap .i-badge:hover { opacity: 0.9; }

.nm-frm .field-hint {
  font-size: 11px;
  color: var(--nm-frm-txt);
  opacity: 0.65;
  padding-left: 4px;
}
.nm-frm .field-hint.error   { color: var(--nm-frm-err); opacity: 1; }
.nm-frm .field-hint.success { color: var(--nm-frm-acc); opacity: 1; }

.nm-frm .neu-textarea {
  width: 100%;
  min-height: 88px;
  border: none;
  outline: none;
  resize: none;
  border-radius: var(--nm-frm-r);
  background: var(--nm-frm-bg);
  box-shadow: var(--nm-frm-neu-in);
  padding: 16px 18px;
  font-family: 'Mulish', system-ui, sans-serif;
  font-size: 14px;
  font-weight: 500;
  color: var(--nm-frm-txt2);
  line-height: 1.6;
  transition: box-shadow 0.22s ease;
}
.nm-frm .neu-textarea::placeholder { color: var(--nm-frm-txt); opacity: 0.45; }
.nm-frm .neu-textarea:focus {
  box-shadow: inset 7px 7px 16px var(--nm-frm-sd), inset -7px -7px 16px var(--nm-frm-sl),
              0 0 0 2.5px rgba(58, 125, 84, 0.25);
}

.nm-frm .select-wrap { position: relative; }
.nm-frm .neu-select {
  width: 100%;
  border: none;
  outline: none;
  appearance: none;
  -webkit-appearance: none;
  border-radius: var(--nm-frm-r);
  background: var(--nm-frm-bg);
  box-shadow: var(--nm-frm-neu-in);
  padding: 14px 42px 14px 18px;
  font-family: 'Mulish', system-ui, sans-serif;
  font-size: 14px;
  font-weight: 500;
  color: var(--nm-frm-txt2);
  cursor: pointer;
  transition: box-shadow 0.22s ease;
}
.nm-frm .neu-select:focus {
  box-shadow: inset 7px 7px 16px var(--nm-frm-sd), inset -7px -7px 16px var(--nm-frm-sl),
              0 0 0 2.5px rgba(58, 125, 84, 0.25);
}
.nm-frm .select-arrow {
  position: absolute;
  right: 16px;
  top: 50%;
  transform: translateY(-50%);
  font-size: 12px;
  pointer-events: none;
  color: var(--nm-frm-txt);
  opacity: 0.6;
}

/* Strength bar */
.nm-frm .strength-bar {
  display: flex;
  gap: 5px;
  margin-top: 4px;
}
.nm-frm .str-seg {
  flex: 1;
  height: 4px;
  border-radius: 2px;
  background: var(--nm-frm-sd);
  opacity: 0.4;
  transition: all 0.3s ease;
}
.nm-frm .str-seg.fill-weak   { background: var(--nm-frm-err); opacity: 1; }
.nm-frm .str-seg.fill-mid    { background: var(--nm-frm-warn); opacity: 1; }
.nm-frm .str-seg.fill-strong { background: var(--nm-frm-acc); opacity: 1; }

/* Checks & radios */
.nm-frm .check-radio-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 24px;
}
.nm-frm .cr-group {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.nm-frm .cr-item {
  display: flex;
  align-items: center;
  gap: 12px;
  cursor: pointer;
  user-select: none;
  background: transparent;
  border: 0;
  padding: 0;
  text-align: left;
  font-family: inherit;
}
.nm-frm .cr-box {
  width: 24px;
  height: 24px;
  border-radius: 7px;
  background: var(--nm-frm-bg);
  box-shadow: var(--nm-frm-neu-sm-in);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  color: transparent;
  flex-shrink: 0;
  transition: all 0.2s ease;
}
.nm-frm .cr-circle {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: var(--nm-frm-bg);
  box-shadow: var(--nm-frm-neu-sm-in);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: all 0.2s ease;
  position: relative;
}
.nm-frm .cr-circle::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) scale(0);
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--nm-frm-acc);
  transition: transform 0.2s cubic-bezier(0.4, 0, 0.2, 1);
  box-shadow: 0 0 6px rgba(58, 125, 84, 0.5);
}
.nm-frm .cr-item.checked .cr-box {
  background: linear-gradient(145deg, var(--nm-frm-acc), var(--nm-frm-ac3));
  box-shadow: 3px 3px 7px rgba(58, 125, 84, 0.4), -2px -2px 5px var(--nm-frm-sl);
  color: #fff;
}
.nm-frm .cr-item.checked .cr-circle::after { transform: translate(-50%, -50%) scale(1); }
.nm-frm .cr-text {
  font-size: 13px;
  font-weight: 500;
  color: var(--nm-frm-txt2);
}
.nm-frm .cr-text small {
  display: block;
  font-size: 11px;
  color: var(--nm-frm-txt);
  font-weight: 400;
  margin-top: 1px;
}

/* Submit row */
.nm-frm .submit-row {
  display: flex;
  gap: 14px;
  align-items: center;
  flex-wrap: wrap;
}
.nm-frm .btn-submit {
  border: none;
  cursor: pointer;
  padding: 14px 36px;
  border-radius: 100px;
  font-family: 'Mulish', system-ui, sans-serif;
  font-size: 14px;
  font-weight: 700;
  color: #fff;
  background: linear-gradient(145deg, var(--nm-frm-acc), var(--nm-frm-ac3));
  box-shadow: 10px 10px 22px rgba(42, 92, 60, 0.35), -5px -5px 14px var(--nm-frm-sl);
  transition: all 0.18s ease;
  letter-spacing: 0.3px;
}
.nm-frm .btn-submit:hover {
  transform: translateY(-2px);
  box-shadow: 12px 16px 28px rgba(42, 92, 60, 0.4), -5px -5px 14px var(--nm-frm-sl);
}
.nm-frm .btn-submit:active {
  box-shadow: inset 5px 5px 12px rgba(0, 0, 0, 0.2);
  transform: scale(0.98);
}
.nm-frm .btn-cancel {
  border: none;
  cursor: pointer;
  padding: 14px 30px;
  border-radius: 100px;
  font-family: 'Mulish', system-ui, sans-serif;
  font-size: 14px;
  font-weight: 600;
  color: var(--nm-frm-txt);
  background: var(--nm-frm-bg);
  box-shadow: var(--nm-frm-neu-sm);
  transition: all 0.15s;
}
.nm-frm .btn-cancel:hover { box-shadow: 7px 7px 16px var(--nm-frm-sd), -7px -7px 16px var(--nm-frm-sl); }
.nm-frm .btn-cancel:active { box-shadow: var(--nm-frm-neu-sm-in); }
.nm-frm .form-note {
  font-size: 11px;
  color: var(--nm-frm-txt);
  opacity: 0.6;
  margin-left: auto;
  font-family: 'DM Mono', ui-monospace, monospace;
}

.nm-frm .div-line {
  height: 1px;
  background: linear-gradient(to right, transparent, var(--nm-frm-sd), transparent);
  opacity: 0.5;
}

@media (max-width: 720px) {
  .nm-frm .card { padding: 32px 22px; }
  .nm-frm .field-grid,
  .nm-frm .check-radio-row { grid-template-columns: 1fr; }
  .nm-frm .form-note { margin-left: 0; }
}
JS
(() => {
  const root = document.querySelector('.nm-frm');
  if (!root) return;

  // Search filter chips
  root.querySelectorAll('[data-nm-frm-chip]').forEach(c => {
    c.addEventListener('click', () => {
      root.querySelectorAll('[data-nm-frm-chip]').forEach(o => o.classList.remove('active'));
      c.classList.add('active');
    });
  });

  // Clear search button
  const search = root.querySelector('[data-nm-frm-search]');
  const clear  = root.querySelector('[data-nm-frm-clear]');
  if (clear && search) {
    clear.addEventListener('click', () => {
      search.value = '';
      search.dispatchEvent(new Event('input'));
      search.focus();
    });
  }

  // Password show/hide toggle
  const pwInput = root.querySelector('[data-nm-frm-pw]');
  const pwToggle = root.querySelector('[data-nm-frm-pw-toggle]');
  if (pwInput && pwToggle) {
    pwToggle.addEventListener('click', () => {
      const showing = pwInput.type === 'text';
      pwInput.type = showing ? 'password' : 'text';
      pwToggle.textContent = showing ? '👁' : '🙈';
    });
  }

  // Email blur validation
  const email = root.querySelector('[data-nm-frm-email]');
  if (email) {
    email.addEventListener('blur', () => {
      const valid = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email.value);
      email.classList.toggle('valid', valid);
      email.classList.toggle('invalid', !valid);
      const hint = email.closest('.field-wrap').querySelector('.field-hint');
      if (hint) {
        hint.classList.toggle('success', valid);
        hint.classList.toggle('error', !valid);
        hint.textContent = valid ? '✓ Valid email.' : '✕ Please enter a valid email.';
      }
    });
  }

  // Checkboxes
  root.querySelectorAll('[data-nm-frm-check]').forEach(item => {
    item.addEventListener('click', () => {
      const checked = item.classList.toggle('checked');
      const box = item.querySelector('.cr-box');
      if (box) box.textContent = checked ? '✓' : '';
    });
  });

  // Radios — exclusive selection within a group
  root.querySelectorAll('[data-nm-frm-radio]').forEach(item => {
    item.addEventListener('click', () => {
      const group = item.closest('.cr-group');
      if (!group) return;
      group.querySelectorAll('[data-nm-frm-radio]').forEach(o => o.classList.remove('checked'));
      item.classList.add('checked');
    });
  });
})();