"""
The core application: view model definitions for the root of the webapp.
"""
from django.utils.translation import pgettext, gettext_lazy as _
from django.urls import reverse

from benefits.core import models

from . import session


class Button:
    """
    Represents a clickable button as styled <a> element (with optional label, optional transparent fallback text):
    * classes: str, str[]
    * id: str
    * fallback_text: str
    * label: str
    * text: str
    * url: str
    * target: str
    * rel: str
    """

    def __init__(self, **kwargs):
        classes = kwargs.get("classes", [])
        if isinstance(classes, str):
            classes = classes.split()

        self.classes = ["btn", "btn-lg"]
        self.classes.extend(classes)
        self.id = kwargs.get("id")
        self.fallback_text = kwargs.get("fallback_text")
        self.label = kwargs.get("label")
        self.text = kwargs.get("text", "Button")
        self.url = kwargs.get("url")
        self.target = kwargs.get("target")
        self.rel = kwargs.get("rel")

    @staticmethod
    def agency_contact_links(agency):
        """Create link buttons for agency contact information."""
        return [
            Button.link(classes="agency", label=agency.long_name, text=agency.phone, url=f"tel:{agency.phone}"),
            Button.link(
                classes="agency", text=agency.info_url, url=agency.info_url, target="_blank", rel="noopener noreferrer"
            ),
        ]

    @staticmethod
    def home(request, text=None):
        """Create a button back to this session's origin."""
        if text is None:
            text = _("core.buttons.return_home")

        return Button.primary(text=text, url=session.origin(request))

    @staticmethod
    def link(**kwargs):
        classes = kwargs.pop("classes", [])
        if isinstance(classes, str):
            classes = classes.split(" ")
        classes.insert(0, "btn-link")
        return Button(classes=classes, **kwargs)

    @staticmethod
    def primary(**kwargs):
        classes = kwargs.pop("classes", [])
        if isinstance(classes, str):
            classes = classes.split(" ")
        classes.insert(0, "btn-primary")
        return Button(classes=classes, **kwargs)

    @staticmethod
    def outline_primary(**kwargs):
        classes = kwargs.pop("classes", [])
        if isinstance(classes, str):
            classes = classes.split(" ")
        classes.insert(0, "btn-outline-primary")
        return Button(classes=classes, **kwargs)

    @staticmethod
    def login(**kwargs):
        """Create a login.gov button, with a login.gov logo and fallback text"""
        btn = Button.primary(fallback_text="Login.gov", id="login", **kwargs)
        return btn

    @staticmethod
    def logout(**kwargs):
        """Create a button that logs user out, with a login.gov button, with a login.gov logo and fallback text"""
        btn = Button.primary(fallback_text="Login.gov", id="login", url=reverse("oauth:logout"), text="", **kwargs)
        return btn

    @staticmethod
    def previous_page(url):
        kwargs = {"id": "previous-page-button", "text": _("core.buttons.previous_page"), "url": url}
        btn = Button(**kwargs)
        btn.classes.append("btn-outline-dark")
        return btn


class Icon:
    """Represents an icon."""

    def __init__(self, icon, alt):
        self.src = f"img/icon/{icon}.svg"
        self.alt = alt


class MediaItem:
    """
    Represents a media item in a list of items:
    * icon: core.viewmodels.Icon
    * details: str, str[]
    * heading: str
    * bullets: str, str[]
    """

    def __init__(self, icon: Icon, details, heading=None, bullets=None):
        self.icon = icon
        if isinstance(details, str):
            self.details = [details]
        elif isinstance(details, list):
            self.details = details
        else:
            self.details = [str(details)]
        self.heading = heading
        if isinstance(bullets, str):
            self.bullets = [bullets]
        elif isinstance(bullets, list):
            self.bullets = bullets


class Page:
    """
    Represents a page of content:
    * title: str
    * icon: core.viewmodels.Icon
    * headline: str
    * paragraphs: str[]
    * form: django.forms.Form
    * forms: django.forms.Form[]
    * button: core.viewmodels.Button
    * buttons: core.viewmodels.Button[]
    * classes: str[]
    """

    def __init__(self, **kwargs):
        self.title = kwargs.get("title")
        if self.title is None:
            self.title = _("core.pages.index.prefix")
        else:
            self.title = f"{_('core.pages.index.prefix')}: {self.title}"

        self.icon = kwargs.get("icon")
        self.headline = kwargs.get("headline")
        self.paragraphs = kwargs.get("paragraphs", [])
        self.steps = kwargs.get("steps")

        self.forms = kwargs.get("forms", [])
        if not isinstance(self.forms, list):
            self.forms = [self.forms]
        if "form" in kwargs:
            self.forms.append(kwargs.get("form"))

        self.buttons = kwargs.get("buttons", [])
        if not isinstance(self.buttons, list):
            self.buttons = [self.buttons]
        if "button" in kwargs:
            self.buttons.append(kwargs.get("button"))

        self.classes = kwargs.get("classes", [])
        if not isinstance(self.classes, list):
            self.classes = self.classes.split(" ")

    def context_dict(self):
        """Return a context dict for a Page."""
        return {"page": self}


class ErrorPage(Page):
    """
    Represents an error page:
    * title: str
    * icon: core.viewmodels.Icon
    * headline: str
    * paragraphs: str[]
    * button: core.viewmodels.Button
    """

    def __init__(self, **kwargs):
        super().__init__(
            title=kwargs.get("title", _("core.pages.error.title")),
            icon=kwargs.get("icon", Icon("sadbus", pgettext("image alt text", "core.icons.sadbus"))),
            headline=kwargs.get("headline", _("core.pages.error.title")),
            paragraphs=kwargs.get("paragraphs", [_("core.pages.server_error.headline")]),
            button=kwargs.get("button"),
        )

    @staticmethod
    def user_error(
        title=_("core.pages.user_error.title"),
        headline=_("core.pages.user_error.headline"),
        paragraphs=[_("core.pages.user_error.p[0]")],
        **kwargs,
    ):
        """Create a new core.viewmodels.ErrorPage instance with defaults for a user error."""
        return ErrorPage(title=title, headline=headline, paragraphs=paragraphs, **kwargs)

    @staticmethod
    def server_error(
        title=_("core.pages.server_error.title"),
        headline=_("core.pages.server_error.title"),
        paragraphs=[_("core.pages.server_error.p[0]")],
        **kwargs,
    ):
        """Create a new core.viewmodels.ErrorPage instance with defaults for a generic server error."""
        return ErrorPage(title=title, headline=headline, paragraphs=paragraphs, **kwargs)

    @staticmethod
    def not_found(
        title=_("core.pages.not_found.title"),
        headline=_("core.pages.not_found.headline"),
        paragraphs=[_("core.pages.not_found.p[0]")],
        **kwargs,
    ):
        """Create a new core.viewmodels.ErrorPage with defaults for a 404."""
        path = kwargs.pop("path", None)
        if path and title:
            title = f"{title}: {path}"
        elif path and not title:
            title = path
        return ErrorPage(title=title, headline=headline, paragraphs=paragraphs, **kwargs)


class PaymentProcessor:
    """
    Represents a core.models.PaymentProcessor:
    * model: core.models.PaymentProcessor
    * access_token_url: str
    * element_id: str
    * color: str
    * [name: str]
    * [loading_text: str]
    """

    def __init__(self, model, access_token_url, element_id, color, name=None, loading_text=_("core.buttons.wait")):
        if isinstance(model, models.PaymentProcessor):
            self.access_token_url = access_token_url
            self.element_id = element_id
            self.color = color
            self.name = name or model.name
            self.loading_text = loading_text
            self.card_tokenize_url = model.card_tokenize_url
            self.card_tokenize_func = model.card_tokenize_func
            self.card_tokenize_env = model.card_tokenize_env

    def context_dict(self):
        """Return a context dict for a PaymentProcessor."""
        return {"payment_processor": self}


class TransitAgency:
    """
    Represents a core.models.TransitAgency:
    * model: core.models.TransitAgency
    """

    def __init__(self, model):
        if isinstance(model, models.TransitAgency):
            self.slug = model.slug
            self.short_name = model.short_name
            self.long_name = model.long_name
            self.agency_id = model.agency_id
            self.merchant_id = model.merchant_id
            self.info_url = model.info_url
            self.phone = model.phone

    def context_dict(self):
        """Return a context dict for a TransitAgency."""
        return {"agency": self}

benefits/core/viewmodels.py
"""
The core application: view model definitions for the root of the webapp.
"""
from django.utils.translation import pgettext, gettext_lazy as _
from django.urls import reverse

from benefits.core import models

from . import session


class Button:
    """
    Represents a clickable button as styled <a> element (with optional label, optional transparent fallback text):
    * classes: str, str[]
    * id: str
    * fallback_text: str
    * label: str
    * text: str
    * url: str
    * target: str
    * rel: str
    """

    def __init__(self, **kwargs):
        classes = kwargs.get("classes", [])
        if isinstance(classes, str):
            classes = classes.split()

        self.classes = ["btn", "btn-lg"]
        self.classes.extend(classes)
        self.id = kwargs.get("id")
        self.fallback_text = kwargs.get("fallback_text")
        self.label = kwargs.get("label")
        self.text = kwargs.get("text", "Button")
        self.url = kwargs.get("url")
        self.target = kwargs.get("target")
        self.rel = kwargs.get("rel")

    @staticmethod
    def agency_contact_links(agency):
        """Create link buttons for agency contact information."""
        return [
            Button.link(classes="agency", label=agency.long_name, text=agency.phone, url=f"tel:{agency.phone}"),
            Button.link(
                classes="agency", text=agency.info_url, url=agency.info_url, target="_blank", rel="noopener noreferrer"
            ),
        ]

    @staticmethod
    def home(request, text=None):
        """Create a button back to this session's origin."""
        if text is None:
            text = _("core.buttons.return_home")

        return Button.primary(text=text, url=session.origin(request))

    @staticmethod
    def link(**kwargs):
        classes = kwargs.pop("classes", [])
        if isinstance(classes, str):
            classes = classes.split(" ")
        classes.insert(0, "btn-link")
        return Button(classes=classes, **kwargs)

    @staticmethod
    def primary(**kwargs):
        classes = kwargs.pop("classes", [])
        if isinstance(classes, str):
            classes = classes.split(" ")
        classes.insert(0, "btn-primary")
        return Button(classes=classes, **kwargs)

    @staticmethod
    def outline_primary(**kwargs):
        classes = kwargs.pop("classes", [])
        if isinstance(classes, str):
            classes = classes.split(" ")
        classes.insert(0, "btn-outline-primary")
        return Button(classes=classes, **kwargs)

    @staticmethod
    def login(**kwargs):
        """Create a login.gov button, with a login.gov logo and fallback text"""
        btn = Button.primary(fallback_text="Login.gov", id="login", **kwargs)
        return btn

    @staticmethod
    def logout(**kwargs):
        """Create a button that logs user out, with a login.gov button, with a login.gov logo and fallback text"""
        btn = Button.primary(fallback_text="Login.gov", id="login", url=reverse("oauth:logout"), text="", **kwargs)
        return btn

    @staticmethod
    def previous_page(url):
        return Button(text=_("core.buttons.previous_page"), url=url)


class Icon:
    """Represents an icon."""

    def __init__(self, icon, alt):
        self.src = f"img/icon/{icon}.svg"
        self.alt = alt


class MediaItem:
    """
    Represents a media item in a list of items:
    * icon: core.viewmodels.Icon
    * details: str, str[]
    * heading: str
    * bullets: str, str[]
    """

    def __init__(self, icon: Icon, details, heading=None, bullets=None):
        self.icon = icon
        if isinstance(details, str):
            self.details = [details]
        elif isinstance(details, list):
            self.details = details
        else:
            self.details = [str(details)]
        self.heading = heading
        if isinstance(bullets, str):
            self.bullets = [bullets]
        elif isinstance(bullets, list):
            self.bullets = bullets


class Page:
    """
    Represents a page of content:
    * title: str
    * icon: core.viewmodels.Icon
    * headline: str
    * paragraphs: str[]
    * form: django.forms.Form
    * forms: django.forms.Form[]
    * button: core.viewmodels.Button
    * buttons: core.viewmodels.Button[]
    * classes: str[]
    """

    def __init__(self, **kwargs):
        self.title = kwargs.get("title")
        if self.title is None:
            self.title = _("core.pages.index.prefix")
        else:
            self.title = f"{_('core.pages.index.prefix')}: {self.title}"

        self.icon = kwargs.get("icon")
        self.headline = kwargs.get("headline")
        self.paragraphs = kwargs.get("paragraphs", [])
        self.steps = kwargs.get("steps")

        self.forms = kwargs.get("forms", [])
        if not isinstance(self.forms, list):
            self.forms = [self.forms]
        if "form" in kwargs:
            self.forms.append(kwargs.get("form"))

        self.buttons = kwargs.get("buttons", [])
        if not isinstance(self.buttons, list):
            self.buttons = [self.buttons]
        if "button" in kwargs:
            self.buttons.append(kwargs.get("button"))

        self.classes = kwargs.get("classes", [])
        if not isinstance(self.classes, list):
            self.classes = self.classes.split(" ")

    def context_dict(self):
        """Return a context dict for a Page."""
        return {"page": self}


class ErrorPage(Page):
    """
    Represents an error page:
    * title: str
    * icon: core.viewmodels.Icon
    * headline: str
    * paragraphs: str[]
    * button: core.viewmodels.Button
    """

    def __init__(self, **kwargs):
        super().__init__(
            title=kwargs.get("title", _("core.pages.error.title")),
            icon=kwargs.get("icon", Icon("sadbus", pgettext("image alt text", "core.icons.sadbus"))),
            headline=kwargs.get("headline", _("core.pages.error.title")),
            paragraphs=kwargs.get("paragraphs", [_("core.pages.server_error.headline")]),
            button=kwargs.get("button"),
        )

    @staticmethod
    def user_error(
        title=_("core.pages.user_error.title"),
        headline=_("core.pages.user_error.headline"),
        paragraphs=[_("core.pages.user_error.p[0]")],
        **kwargs,
    ):
        """Create a new core.viewmodels.ErrorPage instance with defaults for a user error."""
        return ErrorPage(title=title, headline=headline, paragraphs=paragraphs, **kwargs)

    @staticmethod
    def server_error(
        title=_("core.pages.server_error.title"),
        headline=_("core.pages.server_error.title"),
        paragraphs=[_("core.pages.server_error.p[0]")],
        **kwargs,
    ):
        """Create a new core.viewmodels.ErrorPage instance with defaults for a generic server error."""
        return ErrorPage(title=title, headline=headline, paragraphs=paragraphs, **kwargs)

    @staticmethod
    def not_found(
        title=_("core.pages.not_found.title"),
        headline=_("core.pages.not_found.headline"),
        paragraphs=[_("core.pages.not_found.p[0]")],
        **kwargs,
    ):
        """Create a new core.viewmodels.ErrorPage with defaults for a 404."""
        path = kwargs.pop("path", None)
        if path and title:
            title = f"{title}: {path}"
        elif path and not title:
            title = path
        return ErrorPage(title=title, headline=headline, paragraphs=paragraphs, **kwargs)


class PaymentProcessor:
    """
    Represents a core.models.PaymentProcessor:
    * model: core.models.PaymentProcessor
    * access_token_url: str
    * element_id: str
    * color: str
    * [name: str]
    * [loading_text: str]
    """

    def __init__(self, model, access_token_url, element_id, color, name=None, loading_text=_("core.buttons.wait")):
        if isinstance(model, models.PaymentProcessor):
            self.access_token_url = access_token_url
            self.element_id = element_id
            self.color = color
            self.name = name or model.name
            self.loading_text = loading_text
            self.card_tokenize_url = model.card_tokenize_url
            self.card_tokenize_func = model.card_tokenize_func
            self.card_tokenize_env = model.card_tokenize_env

    def context_dict(self):
        """Return a context dict for a PaymentProcessor."""
        return {"payment_processor": self}


class TransitAgency:
    """
    Represents a core.models.TransitAgency:
    * model: core.models.TransitAgency
    """

    def __init__(self, model):
        if isinstance(model, models.TransitAgency):
            self.slug = model.slug
            self.short_name = model.short_name
            self.long_name = model.long_name
            self.agency_id = model.agency_id
            self.merchant_id = model.merchant_id
            self.info_url = model.info_url
            self.phone = model.phone

    def context_dict(self):
        """Return a context dict for a TransitAgency."""
        return {"agency": self}

benefits/core/viewmodels.py
diff --git a/benefits/core/templates/core/includes/previous-page-link.html b/benefits/core/templates/core/includes/previous-page-link.html
index ea0c8c777c..6f81160b13 100644
--- a/benefits/core/templates/core/includes/previous-page-link.html
+++ b/benefits/core/templates/core/includes/previous-page-link.html
@@ -1,3 +1,12 @@
-<div class="row nav-button-row position-absolute">
-    <div class="d-flex align-items-center">{% include "core/includes/button.html" with button=previous_page_button %}</div>
-</div>
+{% if previous_page_button %}
+  <div class="row nav-button-row position-absolute">
+    <div class="d-flex align-items-center">
+      <a id="previous-page-button" class="btn btn-lg btn-outline-dark" href="{{ previous_page_button.url }}" role="button">
+        <svg width="18" height="18" viewBox="0 0 18 18" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+          <path d="M14.25 8.24999H5.355L8.0775 4.97999C8.2048 4.82683 8.26605 4.62937 8.24777 4.43105C8.22948 4.23273 8.13316 4.0498 7.98 3.92249C7.82684 3.79519 7.62938 3.73394 7.43106 3.75223C7.23274 3.77051 7.0498 3.86683 6.9225 4.01999L3.1725 8.51999C3.14727 8.55579 3.12471 8.59339 3.105 8.63249C3.105 8.66999 3.105 8.69249 3.0525 8.72999C3.01851 8.81599 3.00071 8.90753 3 8.99999C3.00071 9.09246 3.01851 9.184 3.0525 9.26999C3.0525 9.30749 3.0525 9.32999 3.105 9.36749C3.12471 9.4066 3.14727 9.4442 3.1725 9.47999L6.9225 13.98C6.99302 14.0647 7.08132 14.1327 7.18113 14.1794C7.28095 14.2261 7.38982 14.2502 7.5 14.25C7.67524 14.2503 7.84507 14.1893 7.98 14.0775C8.05594 14.0145 8.11872 13.9372 8.16473 13.8499C8.21075 13.7627 8.2391 13.6672 8.24815 13.569C8.25721 13.4707 8.2468 13.3717 8.21751 13.2775C8.18823 13.1833 8.14065 13.0958 8.0775 13.02L5.355 9.74999H14.25C14.4489 9.74999 14.6397 9.67097 14.7803 9.53032C14.921 9.38967 15 9.1989 15 8.99999C15 8.80108 14.921 8.61031 14.7803 8.46966C14.6397 8.32901 14.4489 8.24999 14.25 8.24999Z" />
+        </svg>
+        {{ previous_page_button.text }}
+      </a>
+    </div>
+  </div>
+{% endif %}
diff --git a/benefits/core/viewmodels.py b/benefits/core/viewmodels.py
index 243cefbe87..1fdb538c6e 100644
--- a/benefits/core/viewmodels.py
+++ b/benefits/core/viewmodels.py
@@ -93,10 +93,7 @@ def logout(**kwargs):
 
     @staticmethod
     def previous_page(url):
-        kwargs = {"id": "previous-page-button", "text": _("core.buttons.previous_page"), "url": url}
-        btn = Button(**kwargs)
-        btn.classes.append("btn-outline-dark")
-        return btn
+        return Button(text=_("core.buttons.previous_page"), url=url)
 
 
 class Icon:
diff --git a/benefits/eligibility/templates/eligibility/start.html b/benefits/eligibility/templates/eligibility/start.html
index bf369c7340..d3a84078b5 100644
--- a/benefits/eligibility/templates/eligibility/start.html
+++ b/benefits/eligibility/templates/eligibility/start.html
@@ -5,7 +5,7 @@
 {% endblock classes %}
 
 {% block nav-buttons %}
-  {% include "core/includes/previous-page-link.html" with previous_page_button=previous_page_button %}
+  {% include "core/includes/previous-page-link.html" %}
 {% endblock nav-buttons %}
 
 {% block inner-content %}
diff --git a/benefits/static/css/styles.css b/benefits/static/css/styles.css
index fd7c5f64a7..084f985a71 100644
--- a/benefits/static/css/styles.css
+++ b/benefits/static/css/styles.css
@@ -385,11 +385,13 @@ footer .footer-links li a:visited {
   font-weight: var(--medium-font-weight);
   font-size: var(--font-size-14px);
   letter-spacing: var(--body-letter-spacing);
-  padding: 4.5px 2.65px; /* button dimensions are 130 x 32 */
+  padding: 3.5px 2.35px; /* button dimensions are 130 x 32 */
 }
 
 #previous-page-button:hover {
   background: none;
+  color: var(--hover-color);
+  border-color: var(--hover-color);
 }
 
 @media (min-width: 992px) {
@@ -399,16 +401,6 @@ footer .footer-links li a:visited {
   }
 }
 
-#previous-page-button::before {
-  background: url("/static/img/left-arrow.svg") no-repeat;
-  content: "";
-  display: inline-block;
-  height: calc(18rem / 16);
-  position: relative;
-  vertical-align: middle;
-  width: calc(18rem / 16);
-}
-
 /* Forms: Text Inputs */
 /* Form Container: Must use .form-container parent to use these styles */
 
diff --git a/benefits/static/img/left-arrow.svg b/benefits/static/img/left-arrow.svg
deleted file mode 100644
index 06ab969003..0000000000
--- a/benefits/static/img/left-arrow.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
-<path d="M14.25 8.25002H5.355L8.0775 4.98002C8.2048 4.82686 8.26605 4.6294 8.24777 4.43108C8.22948 4.23276 8.13316 4.04983 7.98 3.92252C7.82684 3.79522 7.62938 3.73397 7.43106 3.75226C7.23274 3.77054 7.0498 3.86686 6.9225 4.02002L3.1725 8.52002C3.14727 8.55582 3.12471 8.59342 3.105 8.63252C3.105 8.67002 3.105 8.69252 3.0525 8.73002C3.01851 8.81602 3.00071 8.90756 3 9.00002C3.00071 9.09249 3.01851 9.18403 3.0525 9.27002C3.0525 9.30752 3.0525 9.33002 3.105 9.36752C3.12471 9.40663 3.14727 9.44423 3.1725 9.48002L6.9225 13.98C6.99302 14.0647 7.08132 14.1328 7.18113 14.1794C7.28095 14.2261 7.38982 14.2502 7.5 14.25C7.67524 14.2504 7.84507 14.1893 7.98 14.0775C8.05594 14.0146 8.11872 13.9372 8.16473 13.85C8.21075 13.7627 8.2391 13.6672 8.24815 13.569C8.25721 13.4708 8.2468 13.3717 8.21751 13.2775C8.18823 13.1833 8.14065 13.0958 8.0775 13.02L5.355 9.75002H14.25C14.4489 9.75002 14.6397 9.67101 14.7803 9.53035C14.921 9.3897 15 9.19894 15 9.00002C15 8.80111 14.921 8.61035 14.7803 8.46969C14.6397 8.32904 14.4489 8.25002 14.25 8.25002Z" fill="black"/>
-</svg>

Desktop: Previous Page Button hover color
A clear and concise description of the task.

## Acceptance Criteria

<!-- Remember to consider edge cases -->

- [ ] Hover color is blue, look at Figma

## Additional context

<!-- Add any other context about the task here -->

