# Login page CSS

### Overview

With the login page CSS you can target the below components with full component coverage:

* Login form section
* Input fields and labels
* Buttons and actions
* Branding message and imagery
* Notification containers

Briefly, this is how a branded login page looks like with Ubidots native CSS styling:

<figure><img src="/files/LGenFlq4ZK9kEzIJWqEM" alt=""><figcaption></figcaption></figure>

With the below CSS stylesheet, the login page can be changed into this:

<details>

<summary>Login CSS stylesheet</summary>

```css
/* TYPOGRAPHY */
.login__title,
.login__label,
.login__input,
.login__button,
.login__terms-text,
.login__custom-message {
  font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  letter-spacing: -0.01em;
}

/* BACKGROUND */

.login__wrapper {
  background: linear-gradient(135deg, #000000 0%, #0a0a0a 100%);
}

.login__background {
  background: linear-gradient(135deg, 
    #000000 0%, 
    #0d2d1d 25%,
    #1a4d32 50%, 
    #0d2d1d 75%,
    #000000 100%);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  filter: none;
}

/* CONTAINER */

.login__container {
  background: rgba(12, 12, 12, 0.5);
  border: 1px solid rgba(45, 189, 104, 0.25);
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5),
              0 0 80px rgba(45, 189, 104, 0.1);
  backdrop-filter: blur(24px) saturate(180%);
}

/* FORM SECTION */

.login__section--form {
  background: rgba(10, 10, 10, 0.4);
  backdrop-filter: blur(20px) saturate(180%);
  border-radius: 0.9375rem 0 0 0.9375rem;
  overflow: visible;
}

.login__section--form::before {
  height: 2px;
  background: linear-gradient(90deg, 
    transparent 0%, 
    rgba(45, 189, 104, 0.6) 50%, 
    transparent 100%);
}

.login__section--form::after {
  background: linear-gradient(180deg,
    rgba(255, 255, 255, 0.03) 0%,
    transparent 30%,
    rgba(45, 189, 104, 0.02) 100%);
  border-radius: 0.9375rem 0 0 0.9375rem;
  pointer-events: none;
}

/* LOGO */

.login__logo-link {
  display: block;
  text-align: center;
  margin-bottom: 1.75rem;
}

.login__logo-image {
  width: 200px;
  height: auto;
}

/* IMAGE SECTION */

.login__section--image {
  backdrop-filter: none;
  overflow: hidden;
  border-radius: 0 0.9375rem 0.9375rem 0;
  background-size: cover;
  background-position: center;
}

.login__section--image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}

/* TITLE */

.login__title {
  display: none;
  visibility: hidden;
  opacity: 0;
  height: 0;
  width: 0;
  margin: 0;
  padding: 0;
  overflow: hidden;
}

/* FORM */

.login__form::before {
  content: 'Welcome back';
  display: block;
  color: #E3E3E3;
  font-size: 2.25rem;
  font-weight: 600;
  letter-spacing: -0.03em;
  margin-bottom: 0.5rem;
  text-align: center;
  background: linear-gradient(135deg, #E3E3E3 0%, #2DBD68 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}

.login__form::after {
  content: 'Enter your credentials to access your account';
  display: block;
  color: rgba(227, 227, 227, 0.6);
  font-size: 0.9375rem;
  font-weight: 400;
  margin-bottom: 2rem;
  margin-top: -0.5rem;
}

/* LINKS */

a {
  color: #2DBD68;
  transition: color 0.2s ease;
  font-weight: 500;
  text-decoration: none;
}

a:hover {
  color: #3DD378;
  text-decoration: underline;
}

.login__forgot-link {
  color: #2DBD68;
  transition: color 0.2s ease;
  font-weight: 500;
  text-decoration: none;
}

.login__forgot-link:hover {
  color: #3DD378;
  text-decoration: underline;
}

/* LABELS */

.login__label {
  color: rgba(227, 227, 227, 0.7);
  font-weight: 500;
  font-size: 0.8125rem;
  letter-spacing: 0.01em;
}

/* INPUT FIELDS */

.login__input {
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(45, 189, 104, 0.2);
  color: #E3E3E3;
  transition: all 0.3s ease;
  backdrop-filter: blur(12px) saturate(180%);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3),
              inset 0 1px 0 rgba(255, 255, 255, 0.08),
              inset 0 -1px 0 rgba(0, 0, 0, 0.2);
  font-weight: 400;
  font-size: 0.9375rem;
}

.login__input::placeholder {
  color: rgba(227, 227, 227, 0.35);
  font-weight: 300;
}

.login__input:focus {
  outline: none;
  background: rgba(255, 255, 255, 0.07);
  border-color: rgba(45, 189, 104, 0.5);
  box-shadow: 0 0 0 3px rgba(45, 189, 104, 0.15),
              0 4px 20px rgba(45, 189, 104, 0.2),
              inset 0 1px 0 rgba(255, 255, 255, 0.12);
}

/* ICONS */

.login__icon {
  color: rgba(227, 227, 227, 0.5);
  transition: all 0.2s ease;
  cursor: pointer;
  font-size: 1rem;
}

.login__icon:hover {
  color: #2DBD68;
}

.login__icon[data-tooltip]::after {
  content: attr(data-tooltip);
  background: rgba(15, 15, 15, 0.98);
  border: 1px solid rgba(45, 189, 104, 0.3);
  color: #fff;
  padding: 0.3125rem;
  border-radius: 0.25rem;
  font-family: "Nunito", sans-serif;
  font-size: 0.875rem;
  font-weight: 400;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s;
  backdrop-filter: blur(10px);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.6);
}

.login__icon:hover[data-tooltip]::after {
  opacity: 1;
}

/* BUTTON */

.login__button {
  background: linear-gradient(135deg, 
    rgba(45, 189, 104, 0.9) 0%, 
    rgba(37, 160, 88, 0.9) 100%);
  color: #000000;
  font-weight: 600;
  font-size: 1rem;
  letter-spacing: 0.02em;
  transition: all 0.3s ease;
  box-shadow: 0 4px 20px rgba(45, 189, 104, 0.4),
              inset 0 1px 0 rgba(255, 255, 255, 0.2),
              inset 0 -1px 0 rgba(0, 0, 0, 0.2);
  border: 1px solid rgba(45, 189, 104, 0.6);
  backdrop-filter: blur(10px);
  overflow: hidden;
  animation: fadeInUp 0.6s ease backwards;
  animation-delay: 0.3s;
}

.login__button::before {
  display: block;
  background: linear-gradient(135deg, 
    rgba(255, 255, 255, 0.2) 0%, 
    rgba(255, 255, 255, 0.05) 50%,
    transparent 100%);
  opacity: 1;
  transition: opacity 0.3s ease;
}

.login__button::after {
  display: block;
  width: 200%;
  height: 200%;
  background: linear-gradient(45deg,
    transparent 40%,
    rgba(255, 255, 255, 0.3) 50%,
    transparent 60%);
  opacity: 0;
  transition: opacity 0.6s ease;
}

.login__button:hover {
  background: linear-gradient(135deg, 
    rgba(45, 189, 104, 1) 0%, 
    rgba(37, 160, 88, 1) 100%);
  box-shadow: 0 6px 30px rgba(45, 189, 104, 0.6),
              inset 0 1px 0 rgba(255, 255, 255, 0.3);
  border-color: rgba(45, 189, 104, 0.8);
}

.login__button:hover::after {
  opacity: 1;
}

.login__button:disabled {
  background: rgba(60, 60, 60, 0.3);
  color: rgba(227, 227, 227, 0.3);
  border-color: rgba(227, 227, 227, 0.1);
  box-shadow: none;
}

.login__button:disabled:hover {
  background: rgba(60, 60, 60, 0.3);
}

.login__button-text {
  display: inline;
}

.login__button-loader {
  font-size: 1.5rem;
  color: #000000;
  display: none;
}

.login__button--loading .login__button-loader {
  display: inline-block;
}

/* FOOTER */

.login__terms-text {
  color: rgba(227, 227, 227, 0.5);
  font-size: 0.75rem;
  font-weight: 400;
  font-family: "Nunito", sans-serif;
}

.login__terms-link {
  color: rgba(45, 189, 104, 0.9);
  font-weight: 500;
  text-decoration: none;
}

.login__terms-link:hover {
  color: #3DD378;
  text-decoration: underline;
}

.login__custom-message {
  color: #E3E3E3;
  text-shadow: 0 2px 8px rgba(0, 0, 0, 0.5);
  font-weight: 500;
  letter-spacing: -0.02em;
  font-family: "Inter", sans-serif;
  font-size: 1.5625rem;
}

/* FEEDBACK */

#loader {
  color: #000000;
}

.font-error {
  color: #ff6b6b;
  font-weight: 400;
  background: rgba(255, 107, 107, 0.1);
  padding: 0.75rem 1rem;
  border-radius: 0.5rem;
  border: 1px solid rgba(255, 107, 107, 0.3);
  backdrop-filter: blur(10px);
  font-family: Inter, sans-serif;
  font-size: 0.875rem;
  margin-top: 2rem;
  max-width: 23.875rem;
}

/* RESPONSIVE DESIGN */

@media (min-width: 48rem) {
  .login__section--form {
    width: 35%;
    order: 1;
  }
  
  .login__section--image {
    width: 65%;
    order: 2;
    display: flex;
  }
}

/* INPUT GROUPS */

.login__input-group-container {
  gap: 1.25rem;
}

.login__input-group {
  animation: fadeInUp 0.6s ease backwards;
}

.login__input-group:nth-child(1) {
  animation-delay: 0.1s;
}

.login__input-group:nth-child(2) {
  animation-delay: 0.2s;
}

.login__input-group:nth-child(3) {
  animation-delay: 0.3s;
}

/* ANIMATIONS */

@keyframes fadeInUp {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
```

</details>

<figure><img src="/files/cNUiDXXJrrmqGl7Krik8" alt=""><figcaption></figcaption></figure>

### Login Component Classes Reference

#### Class Hierarchy

The login page follows a strict hierarchical BEM structure with the root container `login__viewport` containing all sub-elements.

{% code expandable="true" %}

```html
login__viewport (Root)
├── login__notification-container
└── login__wrapper
    ├── login__background
    │   └── login__background--app (modifier)
    └── login__container
        ├── login__section
        │   ├── login__section--form (modifier)
        │   ├── login__section--image (modifier)
        │   └── login__section--image-app (modifier)
        │
        ├── [LEFT SIDE - Form Section]
        │   ├── login__logo-link
        │   │   └── login__logo-image
        │   ├── login__title
        │   └── login__form
        │       ├── login__input-group-container
        │       │   └── login__input-group
        │       │       ├── login__input-group--workspace (modifier)
        │       │       ├── login__label
        │       │       ├── login__input
        │       │       └── login__input-wrapper
        │       │           ├── login__input-wrapper--icon (modifier)
        │       │           ├── login__input
        │       │           └── login__icon
        │       │               └── login__icon--eye (modifier)
        │       ├── login__forgot-link
        │       ├── login__actions-container
        │       │   └── login__button
        │       │       ├── login__button--loading (modifier)
        │       │       ├── login__button-text
        │       │       └── login__button-loader
        │       └── login__terms-container
        │           └── login__terms-text
        │               └── login__terms-link
        │
        └── [RIGHT SIDE - Image Section]
            └── login__custom-message
```

{% endcode %}

### Classes by Section

#### Outer Container Classes

The parent class for the outer structure is `login__viewport`.

1. `login__viewport` - Root container for entire login page
2. `login__notification-container` - Container for notifications/alerts
3. `login__wrapper` - Main wrapper around login experience
4. `login__background` - Background layer
   1. `login__background--app` - App-specific background modifier
5. `login__container` - Main login container with border and shadow

***

#### Section Classes

The parent class for the sections is `login__container`.

1. `login__section` - Base section container
   1. `login__section--form` - Form section (LEFT SIDE)
   2. `login__section--image` - Image/branding section (RIGHT SIDE)
   3. `login__section--image-app` - App-specific image section modifier

***

#### Logo & Branding

The parent class for the logo is `login__section--form`.

1. `login__logo-link` - Logo link wrapper
   1. `login__logo-image` - Logo image element

***

#### Title

The parent class for the title is `login__section--form`.

1. `login__title` - Main login heading

***

#### Form Wrapper

The parent class for the form is `login__section--form`.

1. `login__form` - Form wrapper element

***

#### Input Groups

The parent class for the input groups is `login__form`.

1. `login__input-group-container` - Container for all input groups
   1. `login__input-group` - Individual input group wrapper
      1. `login__input-group--workspace` - Workspace input group modifier
      2. `login__label` - Input label element
      3. `login__input` - Input field element
      4. `login__input-wrapper` - Wrapper for inputs with icons
         1. `login__input-wrapper--icon` - Modifier for icon wrapper
         2. `login__input` - Input field element
         3. `login__icon` - Icon element
            1. `login__icon--eye` - Eye icon modifier (password visibility toggle)

***

#### Forgot Password Link

The parent class for the forgot password link is `login__form`.

1. `login__forgot-link` - Forgot password link

***

#### Actions Container

The parent class for the actions container is `login__form`.

1. `login__actions-container` - Container for action buttons
   1. `login__button` - Login button element
      1. `login__button--loading` - Loading state modifier
      2. `login__button-text` - Button text element
      3. `login__button-loader` - Loading spinner element

***

#### Terms Container

The parent class for the terms container is `login__form`.

1. `login__terms-container` - Terms section container
   1. `login__terms-text` - Terms text element
      1. `login__terms-link` - Terms link element

***

#### Custom Message

The parent class for the custom message is `login__section--image`.

1. `login__custom-message` - Custom branding message (tagline/message on right panel)

### CSS Properties Guide

#### Safe to Modif

* `color` - Text colors
* `background` - Background colors and gradients
* `border` - Border styles and colors
* `border-radius` - Corner rounding
* `font-family` - Font choices
* `font-size` - Text sizes
* `font-weight` - Text weights
* `box-shadow` - Shadow effects
* `filter` - Visual filters (grayscale, blur, etc.)
* `backdrop-filter` - Blur and glass morphism effects
* `padding` - Internal spacing
* `margin` - External spacing
* `transform` - Translations, rotations, scaling
* `transition` - Animation transitions
* `opacity` - Transparency
* `width` - Element width
* `height` - Element height

#### Properties to Avoid

* `position: absolute` - May break layout (use relative positioning instead)
* `!important` - Security restriction
* `behavior` - Security restriction
* `expression` - Security restriction
* `javascript:` - Security restriction
* `data:text` - Security restriction
* `vbscript:` - Security restriction
* `file:` - Security restriction
* `ftp:` - Security restriction

#### Responsive Design Considerations

The login page is mobile-responsive by default. Key breakpoints:

* **Mobile (< 768px):** Single column layout, full width form
* **Tablet (768px+):** Split layout appears, form on left, branding on right
* **Desktop (72.5rem+):** Full featured layout with max constraints

Keep these breakpoints in mind when customizing:

```css
@media (min-width: 48rem) {
  .login__section--form {
    width: 50%;
  }
  
  .login__section--image {
    display: flex;
    width: 50%;
  }
}
```

#### Font Customization

Import custom fonts and apply globally:

```css
:root {
  --font-family-primary: "Your Custom Font", sans-serif;
}

*:not([role="icon"]) {
  font-family: var(--font-family-primary);
}
```

#### Transitions and Animations

Use CSS variables for consistent animation timing:

```css
:root {
  --transition-fast: 0.3s ease;
  --transition-normal: 0.2s ease;
}

.login__input {
  transition: border-color var(--transition-fast);
}

.login__button {
  transition: background-color var(--transition-fast), 
              box-shadow var(--transition-fast);
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://dev.ubidots.com/apps/styling-with-css/login-page-css.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
